c++,python实现网络爬虫

前言:

社交网络中用户生成的海量数据,社交网络数据的多样性和复杂性

如何高效地从海量的数据中获取和处理我们需要的信息资源?

该微博爬虫能够从社交网络平台中地提取文本、图片和用户之间的转发关系,并将这些数据结构化存储到图数据库中,为后续的数据分析和挖掘提供支持。

总体思路

在爬取静态的文本与图片时,首先使用libcurl库进行http请求,从指定URL下载网页内容,再使用Gumbo解析HTML内容以提取文本和图像URL,并字符串形式储存,Gumbo DOM树转换为Pugixml文档,使用XPath查找图像URL,将提取的文本内容保存到一个文件中,图像URL保存到另一个文件中。

  在爬取动态的转发关系时,使用selenium库模拟用户操作,动态加载网页,beautifulsoup库解析网页内容,如果文本包含//,则被认为转发自其他用户,提取用户名,否则,被认为转发自原始微博,

  最后将拥有用户id,转发时间,转发来源的csv用pandas库读取内容进行数据处理neo4j储存微博用户与转发关系

设计方法

在设计方法上,本实验综合利用了C++的高效性和Python的灵活性。具体方法如下:

2.1工具与库的选择:为了实现高效的网页下载和HTML解析,选择了libcurl和Gumbo库;为了处理动态网页内容和模拟用户操作,选择了selenium库;为了解析HTML并提取特定数据,选择了BeautifulSoup库;为了处理CSV文件和进行数据分析,选择了pandas库;最后,为了实现数据的图数据库存储,选择了Neo4j。

2.2模块化设计:整个系统分为多个功能模块,包括爬取文本和图片模块、爬取转发关系模块、数据处理与存储模块。每个模块负责特定的任务,模块之间相互协作,共同完成整个数据爬取和存储流程。

3.1性能分析:

3.1.1高效性,算法需要能够高效地处理大量网页请求,特别是对动态加载内容的网页,需要快速响应和处理。

3.1.2资源利用,为了减少对系统资源的占用,包括CPU、内存和网络带宽的使用,以提高系统的整体性能。

3.2功能分析:

3.2.1准确性:算法必须准确地提取网页中的文本、图片URL和用户转发关系,确保数据的完整性和正确性

3.2.2鲁棒性:算法需要具备较强的鲁棒性,能够处理各种异常情况,如网页内容变化、网络连接中断等。

3.2.3扩展性:系统设计需要具备良好的扩展性,便于后续增加新的功能模块,例如爬取用户的点赞关系、评论内容等。

part1:用c++实现文本与图片的爬取,直接把我的代码粘过来,注释很详细

在爬取文本与图片时,首先初始化并且使用libcurl库从指定URL下载网页内容,再使用Gumbo解析HTML内容,提取文本和图像URL,并储存到字符串里面,Gumbo DOM树转换为Pugixml文档,使用XPath查找图像URL将提取的文本内容保存到一个文件中,图像URL保存到另一个文件中。

//(爬取文本,转发关系)
#include <iostream>
#include <fstream>//用于文件操作
#include <string>
#include <curl/curl.h>//用于 libcurl 库,进行 HTTP 请求
#include <gumbo.h>//用于 Gumbo 库,进行 HTML 解析
#include <pugixml.hpp>//用于 pugixml 库,进行 XML 操作
#include <vector>//用于 STL 容器
#include <set>//用于 STL 容器
using namespace std;
size_t WriteCallback(void* contents, size_t size, size_t nmemb, void* userp) {((string*)userp)->append((char*)contents, size * nmemb);return size * nmemb;//返回处理的数据总大小,告诉 libcurl 已经处理了多少数据。
}
string download_url(const string& url, const string& cookie_string) {CURL* curl;//一个指向 CURL 句柄的指针,用于执行 HTTP 请求。CURLcode res;// 用于存储 curl 操作的返回码string readBuffer;//用于存储下载的内容。
//1,初始化 CURLcurl = curl_easy_init();//初始化一个 CURL 句柄,如果初始化成功,返回一个 CURL 句柄,否则返回 nullptr
//2,设置 CURL 选项if (curl) {curl_easy_setopt(curl, CURLOPT_URL, url.c_str());//CURLOPT_URL: 设置要下载的 URLcurl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback);//CURLOPT_WRITEFUNCTION: 设置写入数据的回调函数 WriteCallback。curl_easy_setopt(curl, CURLOPT_WRITEDATA, &readBuffer);//CURLOPT_WRITEDATA: 设置回调函数的用户数据,这里是 readBuffer,用于存储下载的数据。curl_easy_setopt(curl, CURLOPT_COOKIE, cookie_string.c_str());curl_easy_setopt(curl, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36");//CURLOPT_USERAGENT: 设置请求的 User-Agent 字符串,模拟浏览器//3,执行 CURL 请求res = curl_easy_perform(curl);//返回操作的结果码。if (res != CURLE_OK) {cout<< "下载URL内容错误: " << curl_easy_strerror(res) << endl;//转可读字符串}curl_easy_cleanup(curl);//清理}return readBuffer;
}
void search_for_text(GumboNode* node, string& text) {//GumboNode* node: 指向当前处理的 Gumbo 节点的指针;std::string& text: 用于存储提取出的文本内容的字符串引用。if (node->type == GUMBO_NODE_TEXT) {//看是不是文本text.append(node->v.text.text);//是的话追加到字符串text}else if (node->type == GUMBO_NODE_ELEMENT && node->v.element.tag != GUMBO_TAG_SCRIPT && node->v.element.tag != GUMBO_TAG_STYLE) {GumboVector* children = &node->v.element.children;//获取该节点的子节点集合(GumboVector* children)遍历子节点集合,对每个子节点递归调用 search_for_text 函数。for (unsigned int i = 0; i < children->length; ++i) {search_for_text(static_cast<GumboNode*>(children->data[i]), text);}}
}
string extract_text_from_html(const string& html_content) {GumboOutput* output = gumbo_parse(html_content.c_str());//调用 gumbo_parse 函数将 html_content 转换为 C 字符串并解析为 Gumbo DOM 树。output 是解析后的 Gumbo 树的根节点if (!output) {cout << "Gumbo解析失败" << endl;return "";}string text;search_for_text(output->root, text);gumbo_destroy_output(&kGumboDefaultOptions, output);//销毁return text;
}
void traverse_gumbo_node(GumboNode* gumbo_node, pugi::xml_node& pugi_node) {if (gumbo_node->type != GUMBO_NODE_ELEMENT) return;//检查当前 Gumbo 节点是否是元素节点,如果不是则直接返回。GumboElement* element = &gumbo_node->v.element;//获取当前节点的元素部分并将其存储在 element 中const char* tag_name = gumbo_normalized_tagname(element->tag);//获取标准化的标签名,并将其存储在 tag_name 中if (tag_name && tag_name[0]) {//检查标签名是否有效(非空且不为空字符串)pugi::xml_node new_node = pugi_node.append_child(tag_name);// 添加节点的属性GumboVector* attributes = &element->attributes;for (unsigned int i = 0; i < attributes->length; ++i) {//将每个属性添加到 new_node 中。属性的名称和值分别为 attribute->name 和 attribute->value。GumboAttribute* attribute = (GumboAttribute*)attributes->data[i];new_node.append_attribute(attribute->name) = attribute->value;}// 递归处理子节点GumboVector* children = &element->children;for (unsigned int i = 0; i < children->length; ++i) {traverse_gumbo_node((GumboNode*)children->data[i], new_node);}}
}void parse_html(const string& html_content, string& text, set<std::string>& images) {GumboOutput* output = gumbo_parse(html_content.c_str());if (!output) {cout << "Gumbo解析失败" <<endl;return;}pugi::xml_document doc;// 创建一个 pugixml 文档对象 doc。调用 traverse_gumbo_node 函数,将 Gumbo 的 DOM 树转换为 pugixml 的 DOM 树。traverse_gumbo_node(output->root, doc);// 提取文本内容text = extract_text_from_html(html_content);// 提取图像URLfor (pugi::xpath_node xpath_node : doc.select_nodes("//img")) {pugi::xml_node img_node = xpath_node.node();//XPath 表达式 //img 查找 pugixml 文档中所有的 <img> 标签。images.insert(img_node.attribute("src").value());}gumbo_destroy_output(&kGumboDefaultOptions, output);//销毁 Gumbo 解析器的输出对象 output,释放其占用的内存
}// 函数用于将文本内容保存到文件
void save_text_to_file(const string& text, const string& filename) {//const string& text:需要保存的文本内容。const string& filename:目标文件的文件名。ofstream file(filename);//创建一个 ofstream 对象 file,并打开名为 filename 的文件进行输出操作。if (file.is_open()) {file << text;file.close();}else {cout << "打开文件错误: " << filename << endl;}
}// 函数用于将图像URL保存到文件
void save_images_to_file(const set<string>& images, const string& filename) {ofstream file(filename);if (file.is_open()) {for (const string& image : images) {file << image << endl;}file.close();}else {cerr << "打开文件错误: " << filename << endl;}
}int main() {string url = "https://s.weibo.com/weibo?q=%E5%88%98%E6%98%8A%E7%84%B6%20%E6%9C%95%E5%92%8C%E5%AC%9B%E5%AC%9B%E4%BD%95%E6%9B%BE%E6%9C%89%E8%BF%87%E5%AB%8C%E9%9A%99&topic_ad=";string cookie_string = "SINAGLOBAL=5399883731581.21.1696810732360; ariaMouseten=null; UOR=mp.csdn.net,service.weibo.com,mail.qq.com; SUB=_2A25LYf0kDeRhGeFG7VAS9ynPwzyIHXVoH3DsrDV8PUNbmtANLRXWkW1NeTFXOlSZsbpSTgfXcGAbTof6v4B8rIFe; ALF=02_1720523380; ariaDefaultTheme=default; ariaFixed=true; ariaReadtype=1; ariaStatus=true; _s_tentry=-; Apache=6084155699997.418.1718066762994; ULV=1718066762995:15:11:2:6084155699997.418.1718066762994:1717920771762";string html_content = download_url(url, cookie_string);if (html_content.empty()) {cerr << "从URL下载内容失败。" << endl;return 1;}string text;set<std::string> images;parse_html(html_content, text, images);// 保存文本内容到文件save_text_to_file(text, "text_content.txt");// 保存图像URL到文件save_images_to_file(images, "image_urls.txt");cout << "文本内容已保存到 text_content.txt" << std::endl;cout << "图像URL已保存到 image_urls.txt" << std::endl;return 0;
}

part2:python爬取转发关系

在爬取链接时,使用selenium库,beautifulsoup库爬取转发关系,如果文本包含//,则被认为转发自其他用户,提取用户名,否则,被认为转发自原始微博,最后将拥有用户id,转发时间,转发来源的csv用pandas库读取内容进行数据处理,neo4j储存微博用户与转发关系
#最终
from selenium import webdriver
from selenium.webdriver.edge.service import Service
from selenium.webdriver.edge.options import Options
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
import re
import time
from datetime import datetime
import pandas as pd
from bs4 import BeautifulSoup
def initialize_browser(driver_path, options, headers):print("Initializing browser...")service = Service(driver_path)browser = webdriver.Edge(service=service, options=options)browser.execute_cdp_cmd('Network.enable', {})browser.execute_cdp_cmd('Network.setExtraHTTPHeaders', {'headers': headers})print("Browser initialized.")return browser
def wait_for_page_load(browser, timeout, class_name):print("Waiting for page to load...")WebDriverWait(browser, timeout).until(EC.presence_of_element_located((By.CLASS_NAME, class_name)))print("Page loaded.")
def get_page_source(browser):print("Getting page source...")return browser.page_source
def scroll_page(browser):print("Scrolling page...")last_scroll_height = browser.execute_script("return document.body.scrollHeight")while True:browser.execute_script("window.scrollTo(0, document.body.scrollHeight);")time.sleep(5)new_scroll_height = browser.execute_script("return document.body.scrollHeight")if new_scroll_height == last_scroll_height:breaklast_scroll_height = new_scroll_heightprint("Finished scrolling page.")
def parse_page(page_html):print("Parsing page HTML...")soup = BeautifulSoup(page_html, "html.parser")original_poster = soup.find("header", class_="woo-box-flex").find("a", class_="ALink_default_2ibt1")original_user_id = original_poster.get("aria-label")repost_entries = soup.findAll("div", class_="wbpro-scroller-item")print("Finished parsing page HTML.")return original_user_id, repost_entries
def extract_repost_data(repost_entries, original_user_id, processed_user_ids):print("Extracting repost data...")scraped_data = []for entry in repost_entries:# 查找包含转发文本的容器repost_text_container = entry.find("div", class_="text").find("span")if repost_text_container:# 提取容器中的纯文本内容,忽略所有链接text_content = "".join([segment for segment in repost_text_container.strings ifsegment not in repost_text_container.find_all("a")])if "//" in text_content:# 如果文本内容中有"//",表示这是转发的微博,查找用户名的链接username_anchor = repost_text_container.find("a")if username_anchor:username_link = username_anchor.get("href")repost_user = username_link.split("/")[-1]  # 获取用户名repost_info = f"转发自:{repost_user}"else:repost_info = f"转发自:未知用户"  # 处理没有用户名链接的情况else:repost_info = f"转发自:{original_user_id}"  # 直接转发自原始用户# 查找当前用户的IDuser_anchor = entry.find("div", class_="text").find("a", class_="ALink_default_2ibt1")if user_anchor:current_user_id = user_anchor.get_text(strip=True)if current_user_id not in processed_user_ids:processed_user_ids.add(current_user_id)# 查找发布时间信息time_info = entry.find("div", string=re.compile(r'\d{2}-\d{1,2}-\d{1,2} \d{1,2}:\d{2}'))if time_info:post_timestamp = time_info.text.strip()try:# 解析时间格式post_timestamp = datetime.strptime(post_timestamp, '%y-%m-%d %H:%M').strftime('%Y-%m-%d %H:%M:%S')except ValueError:print(f"时间格式错误:{post_timestamp}")# 保存提取的数据scraped_data.append([current_user_id, post_timestamp, repost_info])print(f"用户ID: {current_user_id}, 时间: {post_timestamp}, 转发关系:{repost_info}")print("Finished extracting repost data.")return scraped_datadef save_to_csv(data, output_csv):print("Saving data to CSV...")try:data_frame = pd.DataFrame(data, columns=['user_id', 'time', 'repost_source'])data_frame.to_csv(output_csv, index=False, encoding='utf-8_sig')print(f"数据已保存到 {output_csv}")except Exception as save_error:print("保存CSV文件时出错: ", str(save_error))def main():driver_path = 'D:\\python310\\Scripts\\msedgedriver.exe'options = Options()options.add_argument("--headless")options.add_argument("--disable-gpu")req_headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36 Edg/125.0.0.0","cookie": "SINAGLOBAL=5399883731581.21.1696810732360; UOR=mp.csdn.net,service.weibo.com,mail.qq.com; SUB=_2A25LYf0kDeRhGeFG7VAS9ynPwzyIHXVoH3DsrDV8PUNbmtANLRXWkW1NeTFXOlSZsbpSTgfXcGAbTof6v4B8rIFe; ALF=02_1720523380; ariaDefaultTheme=default; ariaFixed=true; ULV=1718067765857:16:12:3:6228001885489.596.1718067765856:1718066762995; XSRF-TOKEN=1eo5sramGTwy_UcD1QfWa7Wp; WBPSESS=eQZNrz-Wn46RlA5U6QxZX_XMdXGL03Js8_qrxltO2fuSlg9ZjBjrhdtXezA_v15N6m50CLzRQYeD5igzwC15uiMikucPdT9KLGvXo4V-zH6MrZ6iL0wpyjfDdMfGUq7NRQzXh4fOBTtIKuY8cvP8UQ==; ariaReadtype=1; ariaStatus=true"}target_url = "https://weibo.com/6377374546/OhqKDemDv#repost"output_csv = 'pachong.csv'processed_user_ids = set()try:browser = initialize_browser(driver_path, options, req_headers)browser.get(target_url)wait_for_page_load(browser, 20, "detail_wbtext_4CRf9")scroll_page(browser)page_html = get_page_source(browser)original_user_id, repost_entries = parse_page(page_html)scraped_data = extract_repost_data(repost_entries, original_user_id, processed_user_ids)save_to_csv(scraped_data, output_csv)except Exception as overall_error:print("运行中错: ", str(overall_error))finally:browser.quit()if __name__ == "__main__":main()

part3导入neo4j图数据库,进行可视化

#pandas库读取CSV文件中的数据,然后使用Neo4j数据库来存储微博用户及其转发关系
import pandas as pd#pandas用于数据处理,neo4j用于操作Neo4j图数据库
from neo4j import GraphDatabase# 读取 CSV 文件内容,pandas的read_csv函数读取文件内容,存储在DataFrame对象df中。
file_path = r'D:\python project\pythonProject\pachong.csv'  # 修改为你的 CSV 文件路径""
df = pd.read_csv(file_path)# Neo4j 配置
uri = "bolt://localhost:7687"  # 修改为你的 Neo4j URI
user = "neo4j"  # 修改为你的 Neo4j 用户名
password = "zyc679613"  # 修改为你的 Neo4j 密码# GraphDatabase.driver函数连接到Neo4j数据库
driver = GraphDatabase.driver(uri, auth=(user, password))def create_user(tx, user_id):#用于创建用户节点。在Neo4j中,节点可以有多个属性,这里我们使用MERGE命令来确保如果节点已经存在,则不会重复创建相同的节点。tx.run("MERGE (u:User {id: $user_id})", user_id=user_id)def create_relationship(tx, user_id, source_id):#这个函数用于创建转发关系。在Neo4j中,关系用于连接两个节点。这里我们使用MERGE命令来确保如果关系已经存在,则不会重复创建相同的关系。tx.run("""MATCH (u1:User {id: $user_id}), (u2:User {id: $source_id})MERGE (u1)-[:REPOSTED]->(u2)""", user_id=user_id, source_id=source_id)with driver.session() as session:#使用Neo4j的driver对象创建一个会话。driver.session()返回一个上下文管理器,用于执行Cypher查询。# 创建用户节点for user_id in df['user_id'].unique():#遍历DataFrame中不重复的用户IDsession.execute_write(create_user, user_id)#调用create_user函数创建用户节点,并传递用户ID作为参数。# 创建转发关系for index, row in df.iterrows():#遍历DataFrame中的每一行,获取用户ID和转发源。source_id = row['repost_source'].split(":")[-1]  # 从转发源字段中提取转发源ID。转发源字段的格式是"转发自:xxx",这里使用split函数将其拆分,并取最后一个部分作为转发源ID。session.execute_write(create_relationship, row['user_id'], source_id)#调用create_relationship函数创建转发关系,并传递用户ID和转发源ID作为参数。driver.close()

实验结果与分析

C++提取文本与图片的代码通过

提取图片的文件内容

提取文本的文件内容

python爬取转发关系的代码运行过程

python爬取转发关系的csv文件结果

csv文件导入neo4j的节点截图

Neo4j的转发关系截图

  • 总结与心得体会

在完成这次社交网络爬虫系统设计与实现的过程中,我深刻体会到了整个项目从构思到实现的复杂性和挑战性。通过这个项目,不仅提高了我在网络爬虫、数据处理和图数据库等方面的技能,还让我对大规模数据处理和系统设计有了更深入的理解。

在设计阶段,我首先对社交网络数据的特点和目标进行了详细分析。社交网络上的数据不仅包括静态的文本和图片,还包含动态加载的转发关系、评论和点赞等互动信息。因此,系统需要具备处理不同类型网页内容的能力。基于此,我决定采用C++和Python结合的方法:C++负责静态网页的内容下载和解析,Python负责动态网页的内容提取和数据存储。

在项目实施过程中,我遇到了多个挑战。

处理动态网页内容的挑战动态网页内容需要通过JavaScript加载,传统的静态爬虫无法获取这些数据。为了解决这一问题,我引入了selenium库,通过模拟浏览器操作,加载动态网页,并使用BeautifulSoup解析加载完成的网页内容。

数据量大且复杂的挑战,社交网络上的数据量庞大且格式多样,这对系统的性能和数据处理能力提出了很高的要求。为此,我采用了高效的libcurl库进行网页下载,并利用pandas进行数据清洗和处理,确保系统能够高效处理大规模数据。

反爬机制的挑战,很多社交网络平台都有反爬机制,限制频繁的爬虫行为。我通过设置合理的请求头和cookie,模拟真实用户的浏览行为,同时加入了随机延时机制,避免触发反爬机制。

最后我深刻体会到了合适工具选择的重要性,在本项目中,libcurl、Gumbo、selenium、BeautifulSoup、pandas和Neo4j的组合提供了强大的功能支持,使得系统能够高效地完成数据爬取和处理任务,当然其中包括时下载或者是选择相应的库文件都不是一件简单的事情,需要不断去尝试学习。同时我也感受到心态与坚持的魅力,中途有很多次想要放弃,项目其中也因为各种各样的问题停滞不前,,我想这种发现问题,解决问题的能力将伴随我未来的各种项目,希望我能攻克一个又一个问题。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/52568.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【图论】Tarjan算法(强连通分量)

一、Tarjan算法简介 Tarjan算法是一种由美国计算机科学家罗伯特塔杨&#xff08;Robert Tarjan&#xff09;提出的求解有向图强连通分量的线性时间的算法。 二、强连通分量的概念 在有向图 G G G 中&#xff0c;如果任意两个不同的顶点相互可达&#xff0c;则称该有向图是强…

Android高级UI --- canvas

前言 我们先来聊聊&#xff0c;在我们生活中如何绘制一张如下的图。 我们需要两样东西来绘制&#xff1a; 一张纸&#xff08;Android 中的 canvas&#xff09;&#xff1a;用来承载我们绘制的内容。一支笔&#xff08;Android 中的 paint&#xff09;&#xff1a;负责绘制内…

(QT-UI)十四、在时间轴上绘制一段段时间片

本系列预计实现 ①刻度上方文字显示&#xff0c; ②时间轴拖动效果&#xff0c; ③时间轴刻度缩放&#xff0c; ④时间轴和其他控件联动显示&#xff0c; ⑤鼠标放置到时间轴&#xff0c;显示具体时间。 ⑥通过定时器&#xff0c;实时更新时间轴 ⑦时间轴上绘制时间片 完…

linux系统使用 docker 来部署web环境 nginx+php7.4 并配置称 docker-compose-mysql.yml 文件

Docker是一个开源的容器化平台&#xff0c;旨在简化应用程序的创建、部署和管理。它基于OS-level虚拟化技术&#xff0c;通过将应用程序和其依赖项打包到一个称为容器的标准化单元中&#xff0c;使得应用程序可以在任何环境中快速、可靠地运行。 Docker的优势有以下几个方面&a…

重发布实验

一、实验拓扑 二、实验需求 1.如图搭建网络拓扑&#xff0c;所有路由器各自创建一个环回接 口&#xff0c;合理规划IP地址 2.R1-R2-R3-R4-R6之间使用OSPF协议&#xff0c;R4-R5-R6之间使用 RIP协议 3.R1环回重发布方式引入OSPF网络 4.R4/R6上进行双点双向重发布 5.分析网络中出…

VScode | 我想推荐这些插件,好用

系列文章目录 本系列文章主要分享作位前端开发的工具之------VScode的使用分享。 VScode | 我的常用插件分享_vscode 别名跳转-CSDN博客 VScode | 我的常用代码片段&#xff0c;提升开发速度-CSDN博客 VScode | 我会设置文件夹右键用VScode打开_vscode右键打开文件夹-CSDN博…

如何使用ssm实现基于ssm的“游侠”旅游信息管理系统

TOC ssm190基于ssm的“游侠”旅游信息管理系统jsp 绪论 1.1 研究背景 当前社会各行业领域竞争压力非常大&#xff0c;随着当前时代的信息化&#xff0c;科学化发展&#xff0c;让社会各行业领域都争相使用新的信息技术&#xff0c;对行业内的各种相关数据进行科学化&#x…

RocketMQ~刷盘机制、主从复制方式、存储机制

刷盘机制 生产者发布MQ给Brocker&#xff0c;Brocker在存储这些数据的时候&#xff0c;需要进行刷盘&#xff0c;分为同步刷盘和异步刷盘。 在同步刷盘中需要等待一个刷盘成功的ACK&#xff0c;同步刷盘对MQ消息可靠性来说是一种不错的保障&#xff0c;但是性能上会有较大影响…

GoWeb 设置别名和多环境配置

别名 vite.config.ts中添加代码如下即可 //设置别名resolve: {alias: {"": path.resolve(process.cwd(),"src"),//用替代src}}随后即可使用 配置多环境 vite.config.ts中添加代码如下 envDir: ./viteenv,//相对路径随后在项目根目录创建对应的viteenv…

【游戏速递】 小猪冲刺:萌动指尖的极速挑战,小虎鲸Scratch资源站独家献映!

在线玩&#xff1a;Scratch小猪冲刺&#xff1a;全新挑战的几何冒险游戏-小虎鲸Scratch资源站 想象一下&#xff0c;一群憨态可掬的小猪&#xff0c;穿上炫酷的装备&#xff0c;踏上了追逐梦想的赛道。它们或跳跃、或滑行&#xff0c;灵活躲避各种障碍&#xff0c;只为那终点的…

Web API 学习笔记 第四弹

1.时间戳 获取时间戳的方法①date.getTime()②new Date() 2.定时器 console.log(111)setTimeout(()>{console.log(222)},1000)console.log(333) console.log(111)setTimeout(()>{console.log(222)},0)console.log(333) 这两段代码打印结果分别是&#xff1f; 第一段 …

【STM32】驱动OLED屏

其实我没买OLED屏哈哈哈&#xff0c;这个只是学习了&#xff0c;没机会实践。 大部分图片来源&#xff1a;正点原子HAL库课程 专栏目录&#xff1a;记录自己的嵌入式学习之路-CSDN博客 目录 1 显示原理 2 读写方式&#xff1a;8080并口 2.1 支持的指令类型 2.2 …

【Tesla FSD V12的前世今生】从模块化设计到端到端自动驾驶技术的跃迁

自动驾驶技术的发展一直是全球汽车行业的焦点&#xff0c;Tesla的Full-Self Driving&#xff08;FSD&#xff09;系统凭借其持续的技术革新和强大的数据支持&#xff0c;在这个领域独占鳌头。本文将深入介绍Tesla FSD V12的演进历史&#xff0c;从自动驾驶的基础概念入手&#…

数据结构-时间、空间复杂度-详解

数据结构-时间复杂度-详解 1.前言1.1数据结构与算法1.2如何衡量一个算法的好坏1.3复杂度 2.时间复杂度2.1是什么2.2大O符号只保留最高阶项不带系数常数次为O(1) 2.3示例示例2.1示例2.2示例2.3示例2.4 2.4题目 3.空间复杂度3.1是什么3.2大O符号3.3示例示例1示例2示例3示例4 4.题…

2024-08-26 更改驱动器号导致的软件崩溃问题

​ 在给电脑重新分盘时&#xff0c;想把 Software 盘的驱动器号&#xff08;E:&#xff09;改为对应的首字母 S&#xff0c;因此导致了所有软件崩溃。主要原因是软件主要依据驱动器号识别位置&#xff0c;而更改驱动器号后&#xff0c;并不会将软件设置的驱动器号一并更改。 ​…

Docker 的简介

Docker 的简介 为什么会有 Docker环境一致性问题提高资源利用率和可移植性快速部署和伸缩简化管理和维护版本控制和回滚 Docker 的历史dotCloud 时代&#xff08;2010年前&#xff09;Docker 诞生&#xff08;2010-2013&#xff09;快速发展与开源&#xff08;2013-2014&#x…

车载通信框架--- 以太网重连Port口相关思考

我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 屏蔽力是信息过载时代一个人的特殊竞争力,任何消耗你的人和事,多看一眼都是你的不对。非必要不费力证明自己,无利益不试图说服别人,是精神上的节…

手机mkv转换mp4:轻松实现视频格式兼容

如今手机已成为我们日常生活中不可或缺的伴侣&#xff0c;而视频文件则是我们享受娱乐、获取信息的重要来源。然而&#xff0c;由于不同设备和平台对视频格式的支持各有不同&#xff0c;我们有时会遇到无法在手机上播放某些视频文件的问题。 mkv是一种常见的视频格式&#xff…

java接口 controller层接收list集合传参,postman 调用接口时required parameter XXX is not present

开发过程中开发一个java接口 controller层接收list集合传参&#xff0c;然后postman调用一直不成功&#xff0c;报错 使用RequestParam方式&#xff0c;如果postman 调用接口时报错required parameter XXX is not present 可能是&#xff08;value“items”&#xff09;跟你输…

A Neural Probabilistic Language Model

摘要 统计语言建模的一个目标是学习单词序列的联合概率函数。由于维度的诅咒&#xff0c;这在本质上是困难的:我们建议用它自己的武器来对抗它。在提出的方法中&#xff0c;人们同时学习(1)每个单词的分布式表示&#xff08;词向量&#xff09;(即单词之间的相似性)以及(2)表示…