lxml库和Xpath提取网页数据的基础与实战:完整指南与实战【第92篇—提取网页】

使用lxml库和Xpath提取网页数据的基础与实战

在网络爬虫和数据抓取中,从网页中提取所需信息是一项常见的任务。lxml库和Xpath是Python中用于解析和提取HTML/XML数据的强大工具。本文将介绍lxml库的基础知识,以及如何使用Xpath表达式来准确地提取网页数据。

image-20240222110354600

lmxl库简介

lxml是一个用于处理XML和HTML的Python库,它基于C语言的libxml2和libxslt。lxml提供了一个简单而强大的API,使得解析和操作HTML/XML文档变得相对容易。

首先,确保你已经安装了lxml库:

pip install lxml

lmxl库的基础用法

解析HTML/XML文档

from lxml import etree# 从字符串解析HTML
html_string = "<html><body><div>Hello, World!</div></body></html>"
html_tree = etree.fromstring(html_string)# 从文件解析HTML
file_path = "path/to/your/file.html"
html_tree = etree.parse(file_path)

Xpath表达式

Xpath是一种用于在XML文档中定位节点的语言。通过结合lxml库,我们可以使用Xpath表达式来选择和提取数据。

以下是一些常见的Xpath表达式示例:

  • 选取所有的<div>元素://div
  • 选取具有特定class属性的<div>元素://div[@class='classname']
  • 选取第一个<div>元素://div[1]

代码实战:提取网页数据

让我们通过一个实际的例子来演示如何使用lxml和Xpath来提取网页数据。假设我们要从一个简单的HTML页面中提取新闻标题和链接。

import requests
from lxml import etree# 发送HTTP请求获取网页内容
url = "https://example.com/news"
response = requests.get(url)
html_content = response.text# 解析HTML内容
html_tree = etree.HTML(html_content)# 使用Xpath提取新闻标题和链接
titles = html_tree.xpath("//h2[@class='news-title']/a/text()")
links = html_tree.xpath("//h2[@class='news-title']/a/@href")# 打印提取结果
for title, link in zip(titles, links):print(f"Title: {title}\nLink: {link}\n")

在上述代码中,我们首先使用requests库获取网页内容,然后使用lxml的etree.HTML()方法解析HTML。接下来,通过Xpath表达式选择新闻标题和链接,并最终打印出提取的结果。

这是一个简单的例子,实际应用中,你可能需要根据具体网页的结构调整Xpath表达式以适应不同的情况。

通过学习lxml库和Xpath,你可以更轻松地处理和提取网页数据,为你的爬虫和数据抓取任务提供强大的工具。希望这篇文章能帮助你更好地理解和应用这些技术。

进阶用法:处理动态加载和命名空间

在实际的网络爬虫中,经常会遇到动态加载的内容或者命名空间的情况。lxml同样提供了解决这些问题的方法。

处理动态加载内容

有时,网页上的数据是通过JavaScript动态加载的,这样的情况下,通过简单的HTTP请求无法获取到完整的页面内容。可以使用Selenium等工具模拟浏览器行为,或者使用开发者工具分析Ajax请求,然后发送相应的请求获取数据。

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from lxml import etree# 使用Selenium获取动态加载内容
url = "https://example.com/dynamic-page"
driver = webdriver.Chrome()
driver.get(url)# 等待数据加载完成
wait = WebDriverWait(driver, 10)
wait.until(EC.presence_of_element_located((By.XPATH, "//div[@class='dynamic-content']")))# 获取页面内容
html_content = driver.page_source# 关闭浏览器
driver.quit()# 解析HTML内容
html_tree = etree.HTML(html_content)# 使用Xpath提取数据
# ...

处理命名空间

有时,XML文档中可能包含命名空间,这会使Xpath表达式更加复杂。可以使用register_namespace方法来处理命名空间。

from lxml import etree# 解析包含命名空间的XML文档
xml_string = """<root xmlns:ns="http://example.com"><ns:element>Value</ns:element></root>"""
xml_tree = etree.fromstring(xml_string)# 注册命名空间
etree.register_namespace("ns", "http://example.com")# 使用Xpath提取带命名空间的元素
result = xml_tree.xpath("//ns:element/text()", namespaces={"ns": "http://example.com"})# 打印提取结果
print(result)

在这个例子中,我们使用register_namespace方法注册了命名空间,然后在Xpath表达式中使用了命名空间前缀。

通过掌握这些进阶用法,你可以更灵活地应对各种复杂的网页结构和数据提取需求,提高爬虫的适用性和鲁棒性。

错误处理和异常处理

在实际的网络爬虫任务中,经常会面临各种异常情况,如网络连接错误、页面结构变化等。为了确保你的爬虫具有良好的鲁棒性,需要实施适当的错误处理和异常处理机制。

import requests
from lxml import etreeurl = "https://example.com/news"try:# 发送HTTP请求获取网页内容response = requests.get(url)response.raise_for_status()  # 检查请求是否成功html_content = response.text# 解析HTML内容html_tree = etree.HTML(html_content)# 使用Xpath提取数据titles = html_tree.xpath("//h2[@class='news-title']/a/text()")links = html_tree.xpath("//h2[@class='news-title']/a/@href")# 打印提取结果for title, link in zip(titles, links):print(f"Title: {title}\nLink: {link}\n")except requests.exceptions.RequestException as e:print(f"Error during the request: {e}")except etree.XPathError as e:print(f"Error in XPath expression: {e}")except Exception as e:print(f"An unexpected error occurred: {e}")

在上述代码中,我们使用了tryexcept块,分别捕获了requests库可能引发的请求异常和lxml库可能引发的XPath异常。此外,还有一个通用的Exception块,用于捕获其他未预料到的异常。这样,即使在爬虫执行过程中发生了异常,程序也能够 gracefully 处理并给出相应的提示,提高了爬虫的健壮性。

降低爬虫频率和模拟人类行为

在爬取网页数据时,过于频繁的请求可能会导致IP被封禁或者对方服务器的反爬虫机制生效。为了避免这种情况,可以通过设置合适的请求头和模拟人类行为来降低爬虫的频率。

import requests
import time
from random import randinturl = "https://example.com/news"# 设置请求头,模拟浏览器访问
headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36"
}try:# 发送HTTP请求获取网页内容response = requests.get(url, headers=headers)response.raise_for_status()  # 检查请求是否成功html_content = response.text# 解析HTML内容# ...# 模拟人类行为,随机休眠一段时间time.sleep(randint(1, 5))except requests.exceptions.RequestException as e:print(f"Error during the request: {e}")except Exception as e:print(f"An unexpected error occurred: {e}")

在上述代码中,我们通过设置了User-Agent请求头来模拟浏览器的请求,并使用time.sleep()函数来随机休眠一段时间,以模拟人类的访问行为。这有助于降低爬虫的频率,减轻服务器负担,同时避免被封禁的风险。

通过合理设置请求头和模拟人类行为,你可以更好地与目标网站协同工作,提高爬虫的稳定性和可靠性。

存储爬取数据

一旦成功提取了网页数据,你可能希望将数据保存到本地文件或者数据库中以供后续分析或使用。以下是一些存储爬取数据的示例。

存储到本地文件

import requests
from lxml import etreeurl = "https://example.com/news"try:# 发送HTTP请求获取网页内容response = requests.get(url)response.raise_for_status()  # 检查请求是否成功html_content = response.text# 解析HTML内容html_tree = etree.HTML(html_content)# 使用Xpath提取数据titles = html_tree.xpath("//h2[@class='news-title']/a/text()")links = html_tree.xpath("//h2[@class='news-title']/a/@href")# 存储到本地文件with open("news_data.txt", "w", encoding="utf-8") as file:for title, link in zip(titles, links):file.write(f"Title: {title}\nLink: {link}\n\n")except requests.exceptions.RequestException as e:print(f"Error during the request: {e}")except etree.XPathError as e:print(f"Error in XPath expression: {e}")except Exception as e:print(f"An unexpected error occurred: {e}")

在这个例子中,我们使用with open()语句将提取的标题和链接写入到本地文件 “news_data.txt” 中,每个新闻之间空一行。这是一个简单的文本存储方式,适用于小规模的数据。

存储到数据库

如果你需要处理大量数据或者进行更复杂的数据管理,可以考虑将数据存储到数据库中。

import requests
from lxml import etree
import sqlite3url = "https://example.com/news"try:# 发送HTTP请求获取网页内容response = requests.get(url)response.raise_for_status()  # 检查请求是否成功html_content = response.text# 解析HTML内容html_tree = etree.HTML(html_content)# 使用Xpath提取数据titles = html_tree.xpath("//h2[@class='news-title']/a/text()")links = html_tree.xpath("//h2[@class='news-title']/a/@href")# 存储到SQLite数据库with sqlite3.connect("news_database.db") as connection:cursor = connection.cursor()# 创建表cursor.execute("CREATE TABLE IF NOT EXISTS news (title TEXT, link TEXT)")# 插入数据for title, link in zip(titles, links):cursor.execute("INSERT INTO news (title, link) VALUES (?, ?)", (title, link))except requests.exceptions.RequestException as e:print(f"Error during the request: {e}")except etree.XPathError as e:print(f"Error in XPath expression: {e}")except Exception as e:print(f"An unexpected error occurred: {e}")

在这个例子中,我们使用了SQLite数据库,通过连接、创建表和插入数据的方式将爬取的新闻标题和链接存储到数据库中。这种方式更适用于大规模数据以及需要进行复杂查询和分析的情况。

无论你选择哪种方式,存储爬取数据是网络爬虫流程中的重要一步,有助于将数据持久化并方便后续处理。

持续改进与优化

网络爬虫是一个不断学习和优化的过程。在实际应用中,你可能会面临各种情况,例如网站的反爬虫机制、数据结构的变化等。在不断改进与优化中,保持灵活性和适应性是非常重要的。

  • 定期更新Xpath表达式: 网页结构可能会发生变化,导致之前编写的Xpath表达式失效。定期检查并更新Xpath表达式,以适应网页的变化。

  • 处理动态加载内容: 如果网页采用JavaScript动态加载内容,可能需要使用Selenium等工具来模拟浏览器行为,或者通过分析Ajax请求获取数据。

  • 监控爬虫行为: 确保你的爬虫行为合法且符合网站的使用政策。可以使用合适的爬虫框架或工具,以及设置合理的请求频率,避免被封禁或触发反爬虫机制。

  • 处理异常情况: 不同的网站和网络环境可能导致不同类型的异常。根据实际情况完善异常处理机制,提高爬虫的健壮性。

通过持续改进与优化,你将能够构建出更加稳定、高效且可维护的网络爬虫系统。祝愿你在爬虫的旅程中取得更多的成功与经验!

部署爬虫和定时任务

在完成网络爬虫的开发和优化后,你可能希望将爬虫部署到服务器上,并设置定时任务以定期执行爬取任务。这样可以确保你的数据始终是最新的,并且无需手动运行爬虫。

部署到服务器

将爬虫部署到服务器上,可以选择使用云服务(如AWS、Azure、Google Cloud等)或者自己的服务器。确保服务器环境中已经安装了所需的Python环境和相关依赖库。

# 安装依赖库
pip install requests lxml

将你的爬虫代码和相关文件上传到服务器,然后通过终端进入相应的目录,运行你的爬虫脚本。

python your_crawler_script.py

设置定时任务

使用定时任务工具(如cron)可以让你的爬虫在指定的时间间隔内自动运行。在终端中运行以下命令,编辑定时任务表:

crontab -e

添加一行以指定定时任务的执行频率和执行命令。例如,每天凌晨执行一次爬虫:

0 0 * * * python /path/to/your_crawler_script.py

这表示在每天的 00:00 执行指定的Python脚本。你可以根据需求调整执行频率和具体执行命令。

日志记录

在爬虫运行期间,记录日志是非常有用的,可以帮助你追踪爬取过程中的问题,并及时发现异常。使用Python内置的logging模块可以方便地实现日志记录。

import logging# 配置日志
logging.basicConfig(filename='crawler_log.txt', level=logging.INFO, format='%(asctime)s - %(levelname)s: %(message)s')try:# 爬虫逻辑# ...# 记录成功信息logging.info("Crawling job completed successfully.")except Exception as e:# 记录错误信息logging.error(f"An error occurred: {e}")

通过将日志记录到文件中,你可以随时查看爬虫的运行情况,从而更容易发现和解决问题。

安全性注意事项

在爬虫开发和部署过程中,务必注意以下安全性问题:

  • 尊重网站的robots.txt文件: 确保你的爬虫遵守目标网站的robots.txt协议,以避免对方封禁你的IP地址。

  • 模拟人类行为: 使用合适的请求头、随机休眠等方式,模拟人类访问行为,以减少被识别为爬虫的风险。

  • 合法性和道德性: 确保你的爬虫行为是合法的,并遵循相关法律法规。爬取内容时要考虑到道德和隐私问题。

  • 用户代理设置: 使用合适的用户代理(User-Agent),避免使用明显的爬虫标识,以减轻被封禁的可能性。

通过谨慎处理这些安全性问题,可以确保你的爬虫在进行数据抓取的同时,与目标网站保持友好关系,避免引起不必要的问题。

监控与通知

一旦爬虫被部署并设置了定时任务,实时监控爬虫的运行状况并及时处理异常情况是非常重要的。这可以通过引入监控和通知机制来实现。

添加监控机制

可以使用一些监控工具或服务来跟踪你的爬虫运行情况。一些常见的监控项包括:

  • 运行状态: 爬虫是否正常运行,是否出现异常。
  • 内存和CPU使用率: 检查爬虫运行时的系统资源消耗,确保不会导致服务器负载过高。
  • HTTP请求状态码: 监控爬虫请求目标网站时的HTTP状态码,及时发现访问问题。
  • 爬虫速率: 检查爬虫的访问速率,避免频繁请求导致被封禁。

设置通知机制

一旦监控系统检测到异常,可以通过设置通知机制及时通知相关人员。常见的通知方式包括:

  • 邮件通知: 使用邮件服务发送爬虫运行状态的通知。
  • 短信通知: 通过短信服务发送紧急通知。
  • 消息推送: 使用消息推送服务(如Telegram、Slack等)发送即时通知。

以下是一个简单的监控和通知的示例,使用Python的smtplib库发送邮件通知:

import smtplib
from email.mime.text import MIMETextdef send_email(subject, body):sender_email = "your_email@gmail.com"receiver_email = "recipient_email@gmail.com"password = "your_email_password"message = MIMEText(body)message["Subject"] = subjectmessage["From"] = sender_emailmessage["To"] = receiver_emailwith smtplib.SMTP("smtp.gmail.com", 587) as server:server.starttls()server.login(sender_email, password)server.sendmail(sender_email, receiver_email, message.as_string())# 在发生异常时发送邮件通知
try:# 爬虫逻辑# ...except Exception as e:# 记录错误信息error_message = f"An error occurred: {e}"# 发送邮件通知send_email("爬虫异常通知", error_message)

在这个例子中,当爬虫发生异常时,会发送一封包含错误信息的邮件通知到指定邮箱。你可以根据需要调整通知的方式和内容。

整合监控服务

除了自行实现监控和通知,还可以使用专业的监控服务,如Prometheus、Datadog、New Relic等。这些服务提供了丰富的监控和告警功能,能够更方便地管理和跟踪爬虫的运行状态。

通过引入监控和通知机制,可以在爬虫运行过程中及时发现问题,采取相应的措施,提高系统的可靠性和稳定性。

持续改进与优化

随着爬虫的运行,你可能会面临新的挑战和问题。持续改进与优化是一个迭代的过程,可以通过以下方式不断提升爬虫系统的性能和可维护性:

  • 日志分析: 定期分析爬虫的日志,发现并解决潜在问题,了解爬虫运行状况。

  • 性能优化: 根据监控数据,进行性能优化,提高爬虫的效率和响应速度。

  • 定期更新爬虫: 网页结构和反爬虫策略可能会发生变化,定期更新爬虫以适应新的情况。

  • 持续学习: 了解新的技术和工具,不断学习优化爬虫的方法,保持在领域的竞争力。

通过不断改进和优化,你将能够构建出更加稳定、高效且可维护的网络爬虫系统。祝愿你在爬虫的旅程中取得更多的成功与经验!

数据处理与分析

当你成功地爬取了大量的数据后,接下来的关键步骤是对这些数据进行处理和分析。这将有助于你从海量信息中提炼出有用的见解,为业务决策提供支持。

数据清洗与预处理

爬取的数据可能包含一些错误、缺失或不规范的信息。在进行分析之前,需要进行数据清洗和预处理。

import pandas as pd# 假设你已经将爬取的数据存储在CSV文件中
df = pd.read_csv('news_data.csv')# 数据清洗:处理缺失值、去重、处理异常值等
df = df.drop_duplicates()  # 去重
df = df.dropna()  # 删除缺失值# 预处理:转换数据类型、提取关键信息等
df['Date'] = pd.to_datetime(df['Date'])  # 将日期列转为日期类型
df['Title_Length'] = df['Title'].apply(len)  # 添加标题长度列

在这个例子中,我们使用了Python的pandas库进行数据处理。可以根据具体的数据情况进行更复杂的清洗和预处理操作。

数据分析

一旦数据经过清洗和预处理,就可以进行各种分析操作了。以下是一些常见的数据分析任务:

统计信息
# 查看数据的统计信息
summary = df.describe()
print(summary)
排序和筛选
# 按日期排序
df_sorted = df.sort_values(by='Date', ascending=True)# 根据条件筛选数据
df_filtered = df[df['Title_Length'] > 10]
分组与聚合
# 按月份统计新闻数量
df['Month'] = df['Date'].dt.to_period('M')
news_count_by_month = df.groupby('Month').size()
可视化
import matplotlib.pyplot as plt# 绘制新闻数量随时间的趋势图
plt.plot(df['Date'], df.index)
plt.xlabel('Date')
plt.ylabel('News Count')
plt.title('News Count Trend')
plt.show()

数据存储

分析完数据后,可以将结论或需要进一步使用的数据存储下来。

# 将分析结果保存为CSV文件
summary.to_csv('data_summary.csv', index=False)

自动化数据处理与分析

为了实现更高效的数据处理与分析,你可以将上述过程进行自动化,使其成为一个独立的数据处理流程。可以使用Airflow、Luigi等任务调度工具,或者编写脚本进行定期执行。

# 自动执行数据处理与分析脚本
# data_processing_and_analysis.py
import pandas as pd
import matplotlib.pyplot as pltdef data_processing_and_analysis(file_path):# 读取数据df = pd.read_csv(file_path)# 数据清洗与预处理df = df.drop_duplicates()df = df.dropna()df['Date'] = pd.to_datetime(df['Date'])df['Title_Length'] = df['Title'].apply(len)# 数据分析summary = df.describe()news_count_by_month = df.groupby(df['Date'].dt.to_period('M')).size()# 可视化plt.plot(df['Date'], df.index)plt.xlabel('Date')plt.ylabel('News Count')plt.title('News Count Trend')plt.savefig('news_count_trend.png')# 保存结果summary.to_csv('data_summary.csv', index=False)news_count_by_month.to_csv('news_count_by_month.csv')# 在定时任务中调用
data_processing_and_analysis('news_data.csv')

通过将数据处理与分析流程封装成函数或脚本,并定期执行,你可以更方便地管理和维护整个数据处理与分析的流程。

数据可视化与报告

一旦完成数据处理与分析,接下来的关键步骤是将结果以清晰而有力的方式呈现出来。数据可视化和撰写报告是与他人分享你的发现和见解的有效手段。

数据可视化

使用数据可视化工具(如Matplotlib、Seaborn、Plotly等)可以将分析结果转化为易于理解和传达的图表。

import matplotlib.pyplot as plt# 绘制新闻数量随时间的趋势图
plt.plot(df['Date'], df.index)
plt.xlabel('Date')
plt.ylabel('News Count')
plt.title('News Count Trend')
plt.show()

除了趋势图,你还可以创建条形图、饼图、热力图等,根据数据的特点选择最合适的可视化方式。

报告撰写

将你的发现整理成报告,以便他人能够理解你的工作和结论。一个完整的报告通常包括以下内容:

  1. 简介: 介绍你的研究目的、爬取的数据来源和研究问题。

  2. 数据收集: 描述你的爬虫如何工作,爬取了哪些数据。

  3. 数据清洗与预处理: 说明你对数据进行了哪些清洗和预处理操作。

  4. 数据分析: 展示你的分析结果,包括统计信息、趋势图、重要发现等。

  5. 结论: 总结你的研究结果,回答研究问题。

  6. 建议和展望: 提出对数据的进一步研究建议,并展望未来的工作方向。

利用Jupyter Notebook

Jupyter Notebook是一个交互式计算环境,可以在其中编写和执行代码,同时添加文本、图表等元素,非常适合撰写数据分析报告。

# 在Jupyter Notebook中展示趋势图
import matplotlib.pyplot as pltplt.plot(df['Date'], df.index)
plt.xlabel('Date')
plt.ylabel('News Count')
plt.title('News Count Trend')
plt.show()

将报告保存为Jupyter Notebook的形式,你可以分享整个Notebook,使其他人能够轻松地复现你的分析过程。

利用Dashboard工具

使用Dashboard工具(如Tableau、Power BI等)可以创建交互式的仪表板,更灵活地展示和探索数据。

这些工具通常支持从数据源直接连接和导入数据,同时提供各种图表和过滤器,使用户能够自由地进行数据探索。

发布与分享

一旦你的报告和可视化结果准备好,你可以选择不同的方式发布和分享:

  1. 在线平台: 将报告和可视化上传到在线平台,如GitHub、GitLab、Jupyter Notebooks Viewer等,以便他人可以直接查看。

  2. 内部分享: 如果你的研究是为公司或团队进行的,可以在内部分享会议上演示你的报告和发现。

  3. 博客文章: 将你的研究写成博客文章,并分享在个人博客或专业社区中,与其他人交流。

  4. 会议和研讨会: 如果你的研究有足够的深度和重要性,可以考虑提交到相关领域的学术会议或研讨会上,与同行进行交流。

  5. 社交媒体: 利用社交媒体平台分享你的发现,吸引更多关注和反馈。

通过合适的发布和分享方式,你的研究成果将得到更广泛的认可和应用。

总结

在网络爬虫任务中,数据可视化和报告撰写是非常重要的环节,它们帮助你向其他人传达你的发现和见解。通过选择合适的可视化工具和报告撰写方式,你可以更有效地分享你的研究成果,推动业务决策的制定和执行。希望这些建议能够帮助你成功地展示你的网络爬虫研究。祝愿你的报告和可视化工作取得成功!

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

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

相关文章

Flutter Slider自定义滑块样式 Slider的label标签框常显示

1、自定义Slider滑块样式 Flutter Slider控件的滑块系统样式是一个圆点&#xff0c;thumbShape默认样式是RoundSliderThumbShape&#xff0c;如果想要使用其它的样式就需要自定义一下thumbShape&#xff1b; 例如需要一个上图样式的&#xff08;圆点半透明圆形边框&#xff09…

游戏同步+游戏中的网络模块

原文链接&#xff1a;游戏开发入门&#xff08;九&#xff09;游戏同步技术_游戏数据同步机制流程怎么开发-CSDN博客 游戏开发入门&#xff08;十&#xff09;游戏中的网络模块_游戏开发组网-CSDN博客 3.同步技术的基本常识&#xff1a; a.同步给谁&#xff1f;某个用户&…

基于ZYNQ的PCIE高速数据采集卡的设计(二)总体设计与上位机

采集卡总体设计及相关技术 2.1 引言 本课题是来源于雷达辐射源识别项目&#xff0c;需要对雷达辐射源中频信号进行采集传输 和存储。本章基于项目需求&#xff0c;介绍采集卡的总体设计方案。采集卡设计包括硬件设计 和软件设计。首先对采集卡的性能和指标进行分析&#x…

Nginx使用

Nginx 常用命令&#xff1a; nginx -s stop 快速关闭Nginx&#xff0c;可能不保存相关信息&#xff0c;并迅速终止web服务。 nginx -s quit 平稳关闭Nginx&#xff0c;保存相关信息&#xff0c;有安排的结束web服务。 nginx -s reload 因改变了Nginx相关配置…

华清远见作业第三十九天——Qt(第一天)

思维导图&#xff1a; 登录界面&#xff1a; 代码&#xff1a; #include "mainwindow.h" #include<QToolBar> #include<QPushButton> MainWindow::MainWindow(QWidget *parent): QMainWindow(parent) {this->resize(600,400);this->setFixedSize…

32单片机基础:对射式红外传感器计次

接线如下图&#xff1a; 在HardWare建立两个文件&#xff1a;如图 COuntSensor.c 如何配置外部中断,根据下面图&#xff0c;我们需要把外部中断从GPIO到NVIC这一路出现的外设模块都配置好。把这条信号打通就OK了。 1.配置RCC:把我们这里涉及的外设时钟都打开&#xff0c;不打…

算法沉淀——动态规划之简单多状态 dp 问题(上)(leetcode真题剖析)

算法沉淀——动态规划之简单多状态 dp 问题上 01.按摩师02.打家劫舍 II03.删除并获得点数04.粉刷房子 01.按摩师 题目链接&#xff1a;https://leetcode.cn/problems/the-masseuse-lcci/ 一个有名的按摩师会收到源源不断的预约请求&#xff0c;每个预约都可以选择接或不接。在…

【数据结构(顺序表)】

一、什么是数据结构? 数据结构是由“数据”和“结构”两词组合而来。 什么是数据&#xff1f;常见的数值1、2、3、4.....、教务系统里保存的用户信息&#xff08;姓名、性别、年龄、学历等等&#xff09;、网页里肉眼可以看到的信息&#xff08;文字、图片、视频等等&#xff…

二分算法(c++版)

二分的本质是什么&#xff1f; 很多人会认为单调性是二分的本质&#xff0c;但其实其本质并非单调性&#xff0c;只是说&#xff0c;有单调性的可以进行二分&#xff0c;但是有些题目没有单调性我们也可以进行二分。其本质其实是一个边界问题&#xff0c;给定一个条件&#xf…

第九届大数据与计算国际会议 (ICBDC 2024) 即将召开!

2024年第九届大数据与计算国际会议&#xff08;ICBDC 2024&#xff09;将于2024年5月24至26日在泰国曼谷举行。本次会议由朱拉隆功大学工程学院工业工程系主办。ICBDC 2024的宗旨是展示大数据和计算主题相关科学家的最新研究和成果&#xff0c;为来自不同地区的专家代表们提供一…

【MySQL】连接查询和自连接的学习和总结

&#x1f308;个人主页: Aileen_0v0 &#x1f525;热门专栏: 华为鸿蒙系统学习|计算机网络|数据结构与算法 ​&#x1f4ab;个人格言:“没有罗马,那就自己创造罗马~” #mermaid-svg-x4sPmqTXA4yupW1n {font-family:"trebuchet ms",verdana,arial,sans-serif;font-siz…

从零开始学IO_FILE的堆利用:理解IO_FILE之fwrite

​ 要学习基于IO_FILE的堆利用就得了解它的本质&#xff0c;以下会介绍几个主要的IO函数&#xff0c;结合源码和动态调试去学习。 调试环境搭建可参考环境从零开始配置pwn环境&#xff1a;从零开始配置pwn环境&#xff1a;优化pwn虚拟机配置支持libc等指令-CSDN博客 1.在开始上…

【嵌入式实践】【芝麻】【目录】从0到1给电动车添加指纹锁

0. 前言 该项目是基于stm32F103和指纹模块做了一个通过指纹锁控制电动车的小工具。支持添加指纹、删除指纹&#xff0c;电动车进入P档等待时计时&#xff0c;计时超过5min则自动锁车&#xff0c;计时过程中按刹车可中断P档状态&#xff0c;同时中断锁车计时。改项目我称之为“芝…

FlinkCDC详解

1、FlinkCDC是什么 1.1 CDC是什么 CDC是Chanage Data Capture&#xff08;数据变更捕获&#xff09;的简称。其核心原理就是监测并捕获数据库的变动&#xff08;例如增删改&#xff09;&#xff0c;将这些变更按照发生顺序捕获&#xff0c;将捕获到的数据&#xff0c;写入数据…

ThreeJS 几何体顶点position、法向量normal及uv坐标 | UV映射 - 法向量 - 包围盒

文章目录 几何体的顶点position、法向量normal及uv坐标UV映射UV坐标系UV坐标与顶点坐标设置UV坐标案例1&#xff1a;使用PlaneGeometry创建平面缓存几何体案例2&#xff1a;使用BufferGeometry创建平面缓存几何体 法向量 - 顶点法向量光照计算案例1&#xff1a;不设置顶点法向量…

从故宫修建看「软件物料清单」的重要性 @安全历史01

故宫&#xff0c;这座中国传统文化的重要代表和象征性建筑已屹立近600年&#xff0c;是世界上现存规模最大、保存最为完整的木质结构古建筑之一。 故宫之所以能至今保存完好&#xff0c;除持续保护和修缮外&#xff0c;其使用的木材和砖石等材料也经过了精挑细选&#xff0c;保…

数据库增删改查

DDL: 数据定义语言&#xff0c;用来定义数据库对象&#xff08;数据库、表、字段&#xff09;DML: 数据操作语言&#xff0c;用来对数据库表中的数据进行增删改DQL: 数据查询语言&#xff0c;用来查询数据库中表的记录DCL: 数据控制语言&#xff0c;用来创建数据库用户、控制数…

c语言字符函数和字符串函数

目录 1. 字符分类函数2. 字符转换函数3. strlen的使用和模拟实现4. strcpy的使用和模拟实现5. strcat的使用和模拟实现6. strcmp的使用和模拟实现7. strncpy函数的使用8. strncat函数的使用9. strncmp函数的使用10. strstr的使用和模拟实现11. strtok函数的使用12. strerror函数…

设计模式-创建型模式-建造者模式

建造者模式&#xff08;Builder Pattern&#xff09;&#xff1a;将一个复杂对象的构建与它的表示分离&#xff0c;使得同样的构建过程可以创建不同的表示。建造者模式是一种对象创建型模式。 建造者模式一步一步地创建一个复杂的对象&#xff0c;它允许用户只通过指定复杂对象…

Linux-基础知识(黑马学习笔记)

硬件和软件 我们所熟知的计算机是由&#xff1a;硬件和软件组成。 硬件&#xff1a;计算机系统中电子&#xff0c;机械和光电元件等组成的各种物理装置的总称。 软件&#xff1a;是用户和计算机硬件之间的接口和桥梁&#xff0c;用户通过软件与计算机进行交流。 而操作系统…