1905电影网中国地区电影数据分析(一) - 数据采集、清洗与存储
文章目录
- 前言
- 一、数据采集步骤及python库使用版本
- 1. python库使用版本
- 2. 数据采集步骤
- 二、数据采集网页分析
- 1. 分析采集的字段和URL
- 1.1 分析要爬取的数据字段
- 1.2 分析每部电影的URL
- 1.2 分析每页的URL
- 2. 字段元素标签定位
- 三、数据采集代码实现
- 1. 爬取1905电影网分类信息
- 2. 爬取电影主页HTML
- 3. 解析html并把数据保存到csv文件
- 四、数据清洗与存储代码实现
前言
本项目旨在通过爬取1905电影网的电影数据,展示如何使用Python及相关库进行网页数据采集。本项目将详细介绍数据采集的步骤,包括所需的Python库版本、网页分析、数据提取和保存等环节。我们将使用requests库进行网络请求,利用BeautifulSoup进行HTML解析,并将最终的数据保存为CSV文件,便于后续分析和处理。
一、数据采集步骤及python库使用版本
1. python库使用版本
python | requests | bs4 | beautifulsoup4 | soupsieve | lxml | pandas | sqlalchemy | mysql-connector-python | selenium | |
---|---|---|---|---|---|---|---|---|---|---|
版本 | 3.8.5 | 2.31.0 | 0.0.2 | 4.12.3 | 2.6 | 4.9.3 | 2.0.3 | 2.0.36 | 9.0.0 | 4.15.2 |
2. 数据采集步骤
二、数据采集网页分析
1. 分析采集的字段和URL
1.1 分析要爬取的数据字段
如下图所示,红框部分是要爬取的数据,包含电影标题、电影类型、电影时长、电影片名、电影别名、电影上映时间、电影编剧、电影导演、电影主演、电影剧情等字段。
1.2 分析每部电影的URL
访问中国地区的电影地址:https://www.1905.com/mdb/film/list/country-China/
如下图所示,电影是分页显示,每一页有多部电影,点击单部电影后会调转到对应主页,在对应的主页就有需要爬取的数据,所以需要从每页中解析出单个电影的URL。
如下图所示,检查单部电影的源码后可以看到对应的URL。
复制该部电影的URL为:https://www.1905.com/mdb/film/2248201/(2248201是这部电影的ID)
那么就可以通过解析网页获取到每部电影的URL。
1.2 分析每页的URL
如下图所示,检查源码后发现如下规律:
第二页的URL为:https://www.1905.com/mdb/film/list/country-China/o0d0p2.html
第三页的URL为:https://www.1905.com/mdb/film/list/country-China/o0d0p3.html
第四页的URL为:https://www.1905.com/mdb/film/list/country-China/o0d0p4.html
第五页的URL为:https://www.1905.com/mdb/film/list/country-China/o0d0p5.html
由此推断出:
第一页的URL为:https://www.1905.com/mdb/film/list/country-China/o0d0p1.html(o0d0p1.html可省略)
第n页的URL为:https://www.1905.com/mdb/film/list/country-China/o0d0p{n}.html
2. 字段元素标签定位
示例:定位电影标题元素
定位后的CSS选择器内容为:
body > div.topModule.normalCommon.normal_oneLine > div > div > div.topModule_title.clearfix > div.topModule_title_left.fl > h3 > span
三、数据采集代码实现
1. 爬取1905电影网分类信息
import random
import time
from pathlib import Pathimport pandas as pd
import requests
from bs4 import BeautifulSoup'''
爬取1905电影网分类信息(大分类 main_category,小分类 sub_category,链接 sub_category_link)
'''def get_request(url, **kwargs):time.sleep(random.uniform(0.1, 2))print(f'===============================请求地址:{url} ===============================')# 定义一组User-Agent字符串user_agents = [# Chrome'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36','Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36',# Firefox'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/117.0','Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:109.0) Gecko/20100101 Firefox/117.0','Mozilla/5.0 (X11; Linux i686; rv:109.0) Gecko/20100101 Firefox/117.0',# Edge'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36 Edg/117.0.2040.0',# Safari'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.5 Safari/605.1.15',]# 请求头headers = {'User-Agent': random.choice(user_agents)}# 用户名密码认证(私密代理/独享代理)username = ""password = ""proxies = {"http": "http://%(user)s:%(pwd)s@%(proxy)s/" % {"user": username, "pwd": password,"proxy": '36.25.243.5:11768'},"https": "http://%(user)s:%(pwd)s@%(proxy)s/" % {"user": username, "pwd": password,"proxy": '36.25.243.5:11768'}}max_retries = 3for attempt in range(max_retries):try:response = requests.get(url=url, timeout=10, headers=headers, **kwargs)# response = requests.get(url=url, timeout=10, headers=headers, proxies=proxies, **kwargs)if response.status_code == 200:return responseelse:print(f"请求失败,状态码: {response.status_code},正在重新发送请求 (尝试 {attempt + 1}/{max_retries})")except requests.exceptions.RequestException as e:print(f"请求过程中发生异常: {e},正在重新发送请求 (尝试 {attempt + 1}/{max_retries})")# 如果不是最后一次尝试,则等待一段时间再重试if attempt < max_retries - 1:time.sleep(random.uniform(1, 2))print('================多次请求失败,请查看异常情况================')return None # 或者返回最后一次的响应,取决于你的需求def get_soup(markup):return BeautifulSoup(markup=markup, features='lxml')def save_categories_to_csv(response, csv_file_dir='./data_csv/', csv_file_name='category.csv'):"""从HTML响应中提取分类信息并保存到CSV文件。参数:response (requests.Response): 包含HTML内容的响应对象。csv_file_dir (str): CSV文件存储目录,默认为'./data_csv/'。csv_file_name (str): CSV文件名,默认为'category.csv'。"""# 确保目录存在csv_file_dir_path = Path(csv_file_dir)csv_file_dir_path.mkdir(parents=True, exist_ok=True)# 解析HTML文档soup = get_soup(response.text)# 提取分类信息data_list = []tag_srh_group = soup.select("body > div.layout.mainCont.clear > div.leftArea > div > div.col-l-bd > dl.srhGroup.clear")for tag_srh in tag_srh_group:tag_dt = tag_srh.select_one('dt')main_category = tag_dt.text.strip() if tag_dt is not None else Nonetag_a_list = tag_srh.select('a')print(f'===========================解析后的数据如下:===========================')for tag_a in tag_a_list:if tag_a is not None:sub_category = tag_a.text.strip()sub_category_link = 'https://www.1905.com' + tag_a.get('href', '')data_dict = {'main_category': main_category,'sub_category': sub_category,'sub_category_link': sub_category_link}data_list.append(data_dict)print(data_dict)# 创建DataFrame并清理数据df = pd.DataFrame(data_list)df_cleaned = df[df['sub_category'].notna() & (df['sub_category'] != '')]print(f'===========================文件保存路径:{csv_file_dir + csv_file_name}===========================')# 保存到CSV文件df_cleaned.to_csv(csv_file_dir + csv_file_name, index=False, encoding='utf-8-sig')if __name__ == '__main__':res = get_request("https://www.1905.com/mdb/film/search/")save_categories_to_csv(res)
保存后的文件内容如下图所示:
2. 爬取电影主页HTML
import random
import time
from pathlib import Pathimport requests
from bs4 import BeautifulSoupdef get_request(url, **kwargs):time.sleep(random.uniform(0.1, 2))print(f'===============================请求地址:{url} ===============================')# 定义一组User-Agent字符串user_agents = [# Chrome'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36','Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36',# Firefox'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/117.0','Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:109.0) Gecko/20100101 Firefox/117.0','Mozilla/5.0 (X11; Linux i686; rv:109.0) Gecko/20100101 Firefox/117.0',# Edge'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36 Edg/117.0.2040.0',# Safari'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.5 Safari/605.1.15',]# 请求头headers = {'User-Agent': random.choice(user_agents)}# 用户名密码认证(私密代理/独享代理)username = ""password = ""proxies = {"http": "http://%(user)s:%(pwd)s@%(proxy)s/" % {"user": username, "pwd": password,"proxy": '36.25.243.5:11768'},"https": "http://%(user)s:%(pwd)s@%(proxy)s/" % {"user": username, "pwd": password,"proxy": '36.25.243.5:11768'}}max_retries = 3for attempt in range(max_retries):try:response = requests.get(url=url, timeout=10, headers=headers, **kwargs)# response = requests.get(url=url, timeout=10, headers=headers, proxies=proxies, **kwargs)if response.status_code == 200:return responseelse:print(f"请求失败,状态码: {response.status_code},正在重新发送请求 (尝试 {attempt + 1}/{max_retries})")except requests.exceptions.RequestException as e:print(f"请求过程中发生异常: {e},正在重新发送请求 (尝试 {attempt + 1}/{max_retries})")# 如果不是最后一次尝试,则等待一段时间再重试if attempt < max_retries - 1:time.sleep(random.uniform(1, 2))print('================多次请求失败,请查看异常情况================')return None # 或者返回最后一次的响应,取决于你的需求def get_soup(markup):return BeautifulSoup(markup=markup, features='lxml')def save_html_file(save_dir, file_name, content):dir_path = Path(save_dir)# 确保保存目录存在,如果不存在则创建所有必要的父级目录dir_path.mkdir(parents=True, exist_ok=True)# 使用 'with' 语句打开文件以确保正确关闭文件流with open(save_dir + file_name, 'w', encoding='utf-8') as fp:print(f"==============================={save_dir + file_name} 文件已保存===============================")fp.write(str(content))def save_rough_html_file():i = 0save_dir = './rough_html/china/'while True:i = i + 1file_name = f'o0d0p{i}.html'file_path = Path(save_dir + file_name)if file_path.exists() and file_path.is_file():print(f'===============================文件 {file_path} 已存在===============================')continueurl = f'https://www.1905.com/mdb/film/list/country-China/o0d0p{i}.html'response = get_request(url)soup = get_soup(response.text)tag_ul = soup.select_one('body > div.layout.mainCont.clear > div.leftArea > ul')if tag_ul.text.strip() is None or tag_ul.text.strip() == '':print(f'===============================网页爬取完成===============================')breaksave_html_file(save_dir, file_name, response.text)def save_detail_info_html_file():i = 0save_dir = './detail_html/china/'while True:i = i + 1url = f'https://www.1905.com/mdb/film/list/country-China/o0d0p{i}.html'response = get_request(url)soup = get_soup(response.text)tag_ul = soup.select_one('body > div.layout.mainCont.clear > div.leftArea > ul')if tag_ul.text.strip() is None or tag_ul.text.strip() == '':print(f'===============================网页爬取完成===============================')breaktag_li_list = tag_ul.select('li')for tag_li in tag_li_list:tag_a_href = tag_li.find('a').attrs.get('href')movie_url = f'https://www.1905.com{tag_a_href}'movie_id = tag_a_href.split('/')[-2]file_name = f'{movie_id}.html'file_path = Path(save_dir + file_name)if file_path.exists() and file_path.is_file():print(f'===============================文件 {file_path} 已存在===============================')continuedetail_response = get_request(movie_url)if detail_response is None:continuesave_html_file(save_dir, file_name, detail_response.text)if __name__ == '__main__':# save_rough_html_file()save_detail_info_html_file()
爬取后保存的部分html文件如下图所示:
3. 解析html并把数据保存到csv文件
from pathlib import Pathimport pandas as pd
from bs4 import BeautifulSoupdef get_soup(markup):return BeautifulSoup(markup=markup, features='lxml')def parse_detail_html_to_csv():# 定义CSV文件路径csv_file_dir = '../1905movie/data_csv/'csv_file_name = 'detail_1905movie_dataset.csv'csv_file_path = Path(csv_file_dir + csv_file_name)csv_file_dir_path = Path(csv_file_dir)csv_file_dir_path.mkdir(parents=True, exist_ok=True)detail_dir = Path('./detail_html/china/')detail_file_list = detail_dir.rglob('*.html')movie_data_list = []i = 0count = 0for detail_file in detail_file_list:movie_id = str(detail_file).split('\\')[-1].split('.')[0]movie_url = f'https://www.1905.com/mdb/film/{movie_id}/'soup = get_soup(open(file=detail_file, mode='r', encoding='utf-8'))tag_img_url = soup.select_one('div.topModule_bottom_poster.picHover.fl img')movie_img_url = tag_img_url.attrs.get('src') if tag_img_url is not None else Nonetag_div_topmodule_title_right = soup.select_one('div.topModule_title_right.fr')tag_evaluation_name = tag_div_topmodule_title_right.select_one('div.evaluation-name')tag_judge_soon_fl = tag_div_topmodule_title_right.select_one('div.judge-soon.fl')movie_rating = tag_evaluation_name.text if tag_evaluation_name is not None else Nonemovie_status = tag_judge_soon_fl.text if tag_judge_soon_fl is not None else '已上映'tag_topmodule_title_left_fl = soup.select_one('div.topModule_title_left.fl')tag_h3_span = tag_topmodule_title_left_fl.select_one('h3 > span')movie_title = tag_h3_span.text if tag_h3_span is not None else Nonetag_li = tag_topmodule_title_left_fl.select_one('li.topModule_line')movie_genres = str(tag_li.find_next_sibling('li').text.strip()).split() if tag_li is not None else Nonetag_li5 = tag_topmodule_title_left_fl.select_one('div > ul > li:nth-child(5)')movie_duration = tag_li5.text.strip() if tag_li5 is not None else Nonetag_div_left_top = soup.select_one('div#left_top')tag_ul_consmodule_infos = tag_div_left_top.select_one('ul.consModule_infos.consModule_infos_l.fixedWidth.fl') if tag_div_left_top is not None else Nonetag_li_em_release_date = tag_ul_consmodule_infos.find(name='span',string='上映时间') if tag_ul_consmodule_infos is not None else Nonemovie_release_date = tag_li_em_release_date.find_next_sibling().text.strip() if tag_li_em_release_date is not None else Nonetag_li_em_director = tag_ul_consmodule_infos.select_one('li > em > a') if tag_ul_consmodule_infos is not None else Nonemovie_director = tag_li_em_director.text.strip() if tag_li_em_director is not None else Nonetag_ul_consmodule_infos_r = tag_div_left_top.select_one('ul.consModule_infos.consModule_infos_r.fl') if tag_div_left_top is not None else Nonetag_alternative_titles = tag_ul_consmodule_infos_r.select_one('li > em') if tag_ul_consmodule_infos_r is not None else Nonemovie_alternative_titles = tag_alternative_titles.text if tag_alternative_titles is not None else Nonetag_adaptation_source = tag_ul_consmodule_infos_r.find(name='span',string='改编来源') if tag_ul_consmodule_infos_r is not None else Nonemovie_adaptation_source = tag_adaptation_source.find_next_sibling().text if tag_adaptation_source is not None else Nonetag_screenwriter = tag_ul_consmodule_infos_r.select_one('li > em > a') if tag_ul_consmodule_infos_r is not None else Nonemovie_screenwriter = tag_screenwriter.text if tag_screenwriter is not None else Nonetag_lead_actors = soup.select_one('#left_top > div > ul > li')tag_lead_actors_a_list = tag_lead_actors.select('a') if tag_lead_actors is not None else Nonemovie_lead_actors = [tag.text for tag in tag_lead_actors_a_list] if tag_lead_actors_a_list is not None else []tag_plot = soup.select_one('#left_top > ul > li.plotItem.borderStyle > div > a')movie_plot = tag_plot.text if tag_plot is not None else Nonemovie_data_dict = {'movie_id': movie_id,'movie_url': movie_url,'movie_img_url': movie_img_url,'movie_duration': movie_duration,'movie_title': movie_title,'movie_director': movie_director,'movie_release_date': movie_release_date,'movie_status': movie_status,'movie_rating': movie_rating,'movie_genres': movie_genres,'movie_lead_actors': movie_lead_actors,'movie_alternative_titles': movie_alternative_titles,'movie_adaptation_source': movie_adaptation_source,'movie_screenwriter': movie_screenwriter,'movie_plot': movie_plot}i = i + 1print(f'===============================第{i}行数据,解析后的数据如下:===============================')print(movie_data_dict)print('=============================================================================================')movie_data_list.append(movie_data_dict)count = count + 1if count == 200:df = pd.DataFrame(movie_data_list)if not csv_file_path.exists():df.to_csv(csv_file_dir + csv_file_name, index=False, encoding='utf-8-sig')else:df.to_csv(csv_file_dir + csv_file_name, index=False, encoding='utf-8-sig', mode='a', header=False)movie_data_list = []count = 0print(f'===============================解析后的电影数据已保存到 {csv_file_dir + csv_file_name} 文件===============================')if count != 0:df = pd.DataFrame(movie_data_list)df.to_csv(csv_file_dir + csv_file_name, index=False, encoding='utf-8-sig', mode='a', header=False)print(f'===============================解析后的电影数据已全部保存到 {csv_file_dir + csv_file_name} 文件===============================')if __name__ == '__main__':parse_detail_html_to_csv()
保存后的文件内容如下图:
四、数据清洗与存储代码实现
import re
from datetime import datetimeimport pandas as pd
from sqlalchemy import create_enginedef read_csv_to_df(file_path):# 加载CSV文件到DataFramereturn pd.read_csv(file_path, encoding='utf-8')def contains_hours(text):if pd.isna(text): # 检查是否为 NaN 或 Nonereturn Falsepattern = r'\d+\s*(小时|h|hours?|hrs?)'return bool(re.search(pattern, text))def convert_to_minutes(duration_str):parts = str(duration_str).replace('小时', ' ').replace('分钟', '').split()hours = int(parts[0]) if len(parts) > 0 else 0minutes = int(parts[1]) if len(parts) > 1 else 0return hours * 60 + minutes# 定义一个函数来清理和标准化日期
def clean_and_standardize_date(date_str):date_str_cleaned = str(date_str)# 移除括号及其内容if '(' in date_str_cleaned:date_str_cleaned = date_str.split('(')[0]# 尝试匹配并解析完整的日期格式if "年" in date_str_cleaned and "月" in date_str_cleaned and "日" in date_str_cleaned:date_obj = datetime.strptime(date_str_cleaned, "%Y年%m月%d日")elif "年" in date_str_cleaned and "月" in date_str_cleaned:date_obj = datetime.strptime(date_str_cleaned, "%Y年%m月")date_obj = date_obj.replace(day=1) # 设置为该月的第一天elif "年" in date_str_cleaned:date_obj = datetime.strptime(date_str_cleaned, "%Y年")date_obj = date_obj.replace(month=1, day=1) # 设置为该年的第一天else:return None # 如果不符合任何已知模式,则返回 None 或其他默认值return date_obj.strftime("%Y-%m-%d") # 返回标准格式的字符串# 定义函数:清理和转换数据格式
def clean_and_transform(df):# 筛选出电影状态为“已上映”的数据df = df[df['movie_status'] == '已上映']# 删除电影标题为空的行df.dropna(subset=['movie_title'], inplace=True)# 删除id相同的数据df.drop_duplicates(subset=['movie_id'], inplace=True)# 电影时长字段处理df['movie_duration'] = df['movie_duration'].apply(lambda x: x if contains_hours(x) else None)if df['movie_duration'].isnull().sum() != 0:df['movie_duration'] = df['movie_duration'].fillna(method='ffill')df['movie_duration'] = df['movie_duration'].apply(convert_to_minutes)# 发布日期字段处理df['movie_release_date'] = df['movie_release_date'].apply(clean_and_standardize_date)if df['movie_release_date'].isnull().sum() != 0:df['movie_release_date'] = df['movie_release_date'].fillna(method='ffill')# 评分字段处理df['movie_rating'] = df['movie_rating'].astype('float').round(1)if df['movie_rating'].isnull().sum() != 0:df['movie_rating'] = df['movie_rating'].interpolate()# 类型字段处理if df['movie_genres'].isnull().sum() != 0:df['movie_genres'] = df['movie_genres'].fillna(method='ffill')# 其他空值字段处理df = df.fillna('未知')return dfdef save_df_to_db(df):# 设置数据库连接信息db_user = 'root'db_password = 'zxcvbq'db_host = '127.0.0.1' # 或者你的数据库主机地址db_port = '3306' # MySQL默认端口是3306db_name = 'movie1905'# 创建数据库引擎engine = create_engine(f'mysql+mysqlconnector://{db_user}:{db_password}@{db_host}:{db_port}/{db_name}')# 将df写入MySQL表df.to_sql(name='movie1905_china', con=engine, if_exists='replace', index=False)print("所有csv文件的数据已成功清洗并写入MySQL数据库")if __name__ == '__main__':csv_file = r'./data_csv/detail_1905movie_dataset.csv'dataframe = read_csv_to_df(csv_file)dataframe = clean_and_transform(dataframe)save_df_to_db(dataframe)
清洗并存储后的部分数据如下图所示:
相关文章:

1905电影网中国地区电影数据分析(一) - 数据采集、清洗与存储
文章目录 前言一、数据采集步骤及python库使用版本1. python库使用版本2. 数据采集步骤 二、数据采集网页分析1. 分析采集的字段和URL1.1 分析要爬取的数据字段1.2 分析每部电影的URL1.2 分析每页的URL 2. 字段元素标签定位 三、数据采集代码实现1. 爬取1905电影网分类信息2. 爬…...

IPhone16 Plus 设备详情
目录 产品宣传图内部图——前内部图——后设备详细信息 产品宣传图 内部图——前 内部图——后 设备详细信息 信息收集于HubWeb.cn...
埃氏算法C++实现: 快速输出质数( 素数 )
目录 1.简介 算法原理 算法特点 应用场景 2.一般求素数方法 3.埃氏算法求素数 3.1.无动态分配 3.2.有动态分配 1.简介 埃氏算法(Eratosthenes Sieve),全称为埃拉托斯特尼筛法,是一种由古希腊数学家埃拉托斯特尼在公元…...
后端的config包中的常用配置
文章目录 一. CorsConfig二. Knife4jConfig三. MyBatisPlusConfig四. RedisTemplateConfig五. RedissonConfig 一. CorsConfig 全局跨域配置 Configuration public class CorsConfig implements WebMvcConfigurer {Overridepublic void addCorsMappings(CorsRegistry registr…...
基于亿坊PHP框架构建物联网解决方案的优势分析!
在物联网 (IoT) 领域,选到合适的框架对于整个项目的开展也尤为重要。通常情况下,基于PHP的一些主流框架被用户常选择,今天就带大家了解下基于亿坊PHP框架构建物联网解决方案的优势有哪些? 1、开发效率高 在物联网项目中…...

IoTDB结合Mybatis使用示例(增删查改自定义sql等)
IoTDB时序库是当前越来越流行以及基于其优势各大厂商越来越易接受的国产开源时序数据库,针对IoTDB的内容不做过多介绍,在使用该时序库时,往往有一定入门门槛,不同于关系型数据库或文档型数据库那般方便维护和接入开发,…...
skynet 源码阅读 -- 启动主流程
Skynet 启动主流程分析 Skynet 是一个轻量级、高并发的服务器框架。它在启动时会进行一系列初始化操作,并启动多个不同功能的线程(Monitor、Timer、Worker、Socket),从而实现消息分发、定时器、网络I/O等核心功能。本文主要从 ma…...

OpenCV:高通滤波之索贝尔、沙尔和拉普拉斯
目录 简述 什么是高通滤波? 高通滤波的概念 应用场景 索贝尔算子 算子公式 实现代码 特点 沙尔算子 算子公式 实现代码 特点 拉普拉斯算子 算子公式 实现代码 特点 高通滤波器的对比与应用场景 相关阅读 OpenCV:图像滤波、卷积与卷积核…...

UDP 广播组播点播的区别及联系
1、网络IP地址的分类 组播地址是分类编址的IPv4地址中的D类地址,又叫多播地址,他的前四位必须是1110,所以网络地址的二进制取值范围是11100000~11101111对应的十进制为 224~~239。所以以224~239开头的网络地址都是组播地址。 组播地址的功能…...

STM32补充——IAP
0 前置知识: FLASH相关内容:前往STM32补充——FLASH STM32三种烧录方式(看看就行): 1.ISP:In System Programming(在系统编程) 执行芯片厂商的 Bootloader 程序进入 ISP 模式&…...

Jetson Xavier NX (ARM) 使用 PyTorch 安装 Open3D-ML 指南
由于 Jetson 为 ARM64 (aarch64) 的系统架构,所以不能用 pip install 直接安装,需要通过源码编译。 升级系统 JetPack 由于 Open3D-ML 目前只支持 CUDA 10.0 以及 CUDA 11.*,并且 JetPack 的 CUDA 开发环境只有10.2、11.4以及12.2࿰…...

【C++高并发服务器WebServer】-1:Linux中父子进程fork创建及关系、GDB多进程调试
本文目录 一、进程创建二、GDB多进程调试 一、进程创建 在Linux中输入man 2 fork可以查看man文档中的fork的相关函数信息。 fork的作用就是创建一个子进程。 通过fork我们可以知道,创建子进程的时候,复制父进程的信息。 我们看看翻译的man文档信息&am…...

C语言数组详解:从基础到进阶的全面解析
在C语言中,数组是一种基本的数据结构,用于存储多个相同类型的数据。数组的引入使得C语言能够高效地存储和操作大量数据。在任何一个C语言程序中,数组都发挥着极其重要的作用。无论是在算法实现、数据存储、还是在复杂程序的设计中,…...

docker的前世今生
docker来自哪里? 从我们运维部署的历史来看,宿主机从最初的物理机到虚拟机,再到docker,一步步演进到现在。技术演进其实是为了解决当前技术的痛点,那我们来看看有哪些痛点以及如何克服痛点的。 物理机 一般来说&…...
python实现施瓦茨-克里斯托费尔【全网首个】根据用户输入推测函数
上代码: from sympy import symbols, integrate, simplify from sympy.plotting import plotn int(input("n:")) if n < 2:print("Error: Must n > 2") i 0 a [] aef [] A [] x, y symbols(x y) z, w symbols(z w)while i < n…...

c语言中的数组(上)
数组的概念 数组是⼀组相同类型元素的集合; 数组中存放的是1个或者多个数据,但是数组元素个数不能为0。 数组中存放的多个数据,类型是相同的。 数组分为⼀维数组和多维数组,多维数组⼀般⽐较多⻅的是⼆维数组。 数组创建 在C语言…...

Unity3D仿星露谷物语开发25之创建时钟界面
1、目标 在时钟界面显示当前时钟信息,同时设置特殊按钮可以快速推进时间用于测试。 2、创建GameClock.cs脚本 在Assets -> Scripts -> TimeSystem目录下创建GameClock.cs脚本。 代码如下: using System.Collections; using System.Collections…...

数据结构测试题1
一、选择题: 1.若长度为n的钱性表采用顺序存储结构,删除它的第i数据元素之前,需要先依次向前移动( )个数据元素。( C ) A .n-i B.ni C.n-i-1 D.n-i1 2.在单链表中,已知q指的结点是p指的结点的直接前驱结点&am…...
android wifi AsyncChannel(WifiManager和WifiP2pManager)
AynscChannel的讲解 [Android]AsyncChannel介绍-CSDN博客 WifiP2pManager里的channel的使用理解 WifiP2pManager.java public void createGroup(Channel c, ActionListener listener) {checkChannel(c);c.mAsyncChannel.sendMessage(CREATE_GROUP, WifiP2pGroup.NETWORK_ID_PE…...

【Image Captioning】DynRefer
DynRefer是由中国科学院大学于2024年提出的用于1种用于区域级多模态任务的模型。DynRefer 通过模拟人类视觉认知过程,显著提升了区域级多模态识别能力。通过引入人眼的动态分辨率机制, 能够以同时完成区域识别、区域属性检测和区域字幕生成任务。 文章链…...

基于ASP.NET+ SQL Server实现(Web)医院信息管理系统
医院信息管理系统 1. 课程设计内容 在 visual studio 2017 平台上,开发一个“医院信息管理系统”Web 程序。 2. 课程设计目的 综合运用 c#.net 知识,在 vs 2017 平台上,进行 ASP.NET 应用程序和简易网站的开发;初步熟悉开发一…...

微信小程序 - 手机震动
一、界面 <button type"primary" bindtap"shortVibrate">短震动</button> <button type"primary" bindtap"longVibrate">长震动</button> 二、js逻辑代码 注:文档 https://developers.weixin.qq…...
Java多线程实现之Callable接口深度解析
Java多线程实现之Callable接口深度解析 一、Callable接口概述1.1 接口定义1.2 与Runnable接口的对比1.3 Future接口与FutureTask类 二、Callable接口的基本使用方法2.1 传统方式实现Callable接口2.2 使用Lambda表达式简化Callable实现2.3 使用FutureTask类执行Callable任务 三、…...
Spring Boot面试题精选汇总
🤟致敬读者 🟩感谢阅读🟦笑口常开🟪生日快乐⬛早点睡觉 📘博主相关 🟧博主信息🟨博客首页🟫专栏推荐🟥活动信息 文章目录 Spring Boot面试题精选汇总⚙️ **一、核心概…...

有限自动机到正规文法转换器v1.0
1 项目简介 这是一个功能强大的有限自动机(Finite Automaton, FA)到正规文法(Regular Grammar)转换器,它配备了一个直观且完整的图形用户界面,使用户能够轻松地进行操作和观察。该程序基于编译原理中的经典…...

ABAP设计模式之---“简单设计原则(Simple Design)”
“Simple Design”(简单设计)是软件开发中的一个重要理念,倡导以最简单的方式实现软件功能,以确保代码清晰易懂、易维护,并在项目需求变化时能够快速适应。 其核心目标是避免复杂和过度设计,遵循“让事情保…...
React---day11
14.4 react-redux第三方库 提供connect、thunk之类的函数 以获取一个banner数据为例子 store: 我们在使用异步的时候理应是要使用中间件的,但是configureStore 已经自动集成了 redux-thunk,注意action里面要返回函数 import { configureS…...

基于 TAPD 进行项目管理
起因 自己写了个小工具,仓库用的Github。之前在用markdown进行需求管理,现在随着功能的增加,感觉有点难以管理了,所以用TAPD这个工具进行需求、Bug管理。 操作流程 注册 TAPD,需要提供一个企业名新建一个项目&#…...

【电力电子】基于STM32F103C8T6单片机双极性SPWM逆变(硬件篇)
本项目是基于 STM32F103C8T6 微控制器的 SPWM(正弦脉宽调制)电源模块,能够生成可调频率和幅值的正弦波交流电源输出。该项目适用于逆变器、UPS电源、变频器等应用场景。 供电电源 输入电压采集 上图为本设计的电源电路,图中 D1 为二极管, 其目的是防止正负极电源反接, …...

push [特殊字符] present
push 🆚 present 前言present和dismiss特点代码演示 push和pop特点代码演示 前言 在 iOS 开发中,push 和 present 是两种不同的视图控制器切换方式,它们有着显著的区别。 present和dismiss 特点 在当前控制器上方新建视图层级需要手动调用…...