多线程爬虫优化:快速爬取并写入CSV

在数据驱动的时代,爬虫技术已成为获取网络数据的重要手段。然而,随着数据量的不断增加,单线程爬虫的效率逐渐难以满足需求。多线程爬虫通过并行处理,能够显著提升爬取速度,同时将数据快速写入CSV文件,为后续的数据分析和应用提供支持。本文将详细介绍多线程爬虫的优化策略,并通过一个完整的实战案例展示如何实现高效的数据爬取和存储。

一、多线程爬虫的优势

多线程爬虫通过同时运行多个线程,可以充分利用计算机的多核处理器资源,显著提升爬取效率。以下是多线程爬虫的主要优势:

  1. 提高爬取速度:多线程爬虫可以同时请求多个网页,大大缩短了爬取时间。
  2. 优化资源利用:在等待网络响应时,其他线程可以继续工作,避免了单线程爬虫的等待时间浪费。
  3. 增强容错能力:即使某个线程因网络问题或目标网站的限制而失败,其他线程仍可以继续运行,确保爬取任务的稳定性。

二、技术栈介绍

在本项目中,我们将使用以下技术栈:

  • Python:一种广泛使用的高级编程语言,具有丰富的库和框架,适合进行爬虫开发。
  • Requests:一个Python库,用于发送HTTP请求,方便我们从网页获取数据。
  • BeautifulSoup:一个用于解析HTML和XML文档的Python库,可以帮助我们提取网页中的数据。
  • Pandas:一个强大的数据分析库,支持数据清洗、转换和存储。
  • Threading:Python内置的多线程库,用于实现多线程爬虫。
  • CSV:一种简单的文本文件格式,用于存储表格数据,便于后续的数据分析。

三、实战案例:多线程爬虫实现

1. 确定目标网站

假设我们要爬取一个电商平台的商品信息,包括商品名称、价格、销量和评价。目标网站的URL为 <font style="color:rgba(0, 0, 0, 0.9);background-color:rgba(0, 0, 0, 0.03);">https://example.com/products</font>,商品信息分布在多个页面中。

2. 分析网页结构

在开始编写爬虫之前,我们需要先分析目标网页的结构。通过浏览器的开发者工具,我们可以查看网页的HTML代码,找到商品信息所在的标签和类名。

3. 编写多线程爬虫代码

以下是多线程爬虫的实现代码:

import requests
from bs4 import BeautifulSoup
import pandas as pd
import threading
from queue import Queue
import time# 代理信息
proxyHost = "www.16yun.cn"
proxyPort = "5445"
proxyUser = "16QMSOML"
proxyPass = "280651"# 构造代理
proxies = {"http": f"http://{proxyUser}:{proxyPass}@{proxyHost}:{proxyPort}","https": f"https://{proxyUser}:{proxyPass}@{proxyHost}:{proxyPort}",
}# 全局变量
url_queue = Queue()  # 存储待爬取的URL
data_queue = Queue()  # 存储爬取到的数据
headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3"
}# 爬取单个页面
def crawl_page(url):try:response = requests.get(url, headers=headers, proxies=proxies, timeout=10)response.raise_for_status()  # 检查请求是否成功soup = BeautifulSoup(response.text, "html.parser")products = soup.find_all("div", class_="product-item")for product in products:name = product.find("h2", class_="product-name").text.strip()price = product.find("span", class_="product-price").text.strip()sales = product.find("span", class_="product-sales").text.strip()reviews = product.find("span", class_="product-reviews").text.strip()data_queue.put({"商品名称": name,"价格": price,"销量": sales,"评价": reviews})except requests.exceptions.RequestException as e:print(f"请求失败:{url}, 错误:{e}")print("请检查网页链接的合法性,或者稍后重试。")# 爬虫线程
def worker():while not url_queue.empty():url = url_queue.get()crawl_page(url)url_queue.task_done()# 主函数
def main():# 假设目标网站有多个页面base_url = "https://example.com/products?page="for page in range(1, 11):  # 爬取前10页url_queue.put(base_url + str(page))# 创建多个线程threads = []for _ in range(5):  # 启动5个线程t = threading.Thread(target=worker)t.start()threads.append(t)# 等待所有线程完成for t in threads:t.join()# 将数据存储为CSV文件data_list = []while not data_queue.empty():data_list.append(data_queue.get())df = pd.DataFrame(data_list)df.to_csv("products.csv", index=False, encoding="utf-8-sig")print("数据已成功保存到CSV文件中。")if __name__ == "__main__":start_time = time.time()main()end_time = time.time()print(f"总耗时:{end_time - start_time:.2f}秒")

四、代码解析

1. 线程安全队列

在多线程环境中,我们需要确保数据的线程安全性。<font style="color:rgba(0, 0, 0, 0.9);background-color:rgba(0, 0, 0, 0.03);">queue.Queue</font> 是一个线程安全的队列,用于存储待爬取的URL和爬取到的数据。

2. 爬虫线程

我们定义了一个 <font style="color:rgba(0, 0, 0, 0.9);background-color:rgba(0, 0, 0, 0.03);">worker</font> 函数,每个线程都会调用该函数。线程会从 <font style="color:rgba(0, 0, 0, 0.9);background-color:rgba(0, 0, 0, 0.03);">url_queue</font> 中获取URL,爬取数据后将结果存入 <font style="color:rgba(0, 0, 0, 0.9);background-color:rgba(0, 0, 0, 0.03);">data_queue</font>

3. 数据存储

在所有线程完成后,我们将 <font style="color:rgba(0, 0, 0, 0.9);background-color:rgba(0, 0, 0, 0.03);">data_queue</font> 中的数据转换为Pandas的DataFrame,并保存为CSV文件。

五、性能优化

1. 线程数量

线程数量的选择需要根据目标网站的响应速度和服务器性能进行调整。过多的线程可能会导致目标网站拒绝服务,而过少的线程则无法充分利用多核处理器的优势。在本案例中,我们选择了5个线程。

2. 防止被封禁

为了避免因频繁请求而被目标网站封禁IP,可以在代码中加入适当的延时。例如,在每次请求之间添加 <font style="color:rgba(0, 0, 0, 0.9);background-color:rgba(0, 0, 0, 0.03);">time.sleep(1)</font>

3. 错误处理

在爬取过程中,可能会遇到网络请求失败、目标网站结构变化等问题。通过捕获异常并记录错误信息,可以确保爬虫的稳定性。

六、数据分析

完成数据爬取和存储后,我们可以使用Pandas进行数据分析。以下是简单的数据分析代码:

import pandas as pd# 加载CSV文件
df = pd.read_csv("products.csv")# 查看数据的前几行
print(df.head())# 数据清洗
df.drop_duplicates(inplace=True)  # 删除重复数据
df.dropna(inplace=True)  # 删除缺失值# 数据分析
print("平均价格:", df["价格"].mean())
print("最高销量商品:", df.loc[df["销量"].idxmax()]["商品名称"])
print("评价分布:", df["评价"].value_counts())# 数据可视化
import matplotlib.pyplot as pltdf["价格"].plot(kind="hist", bins=20, title="价格分布")
plt.xlabel("价格")
plt.ylabel("商品数量")
plt.show()

七、总结

通过多线程爬虫技术,我们能够显著提升数据爬取的效率,并将数据快速存储为CSV文件。在实际应用中,合理选择线程数量、优化错误处理和防止被封禁是确保爬虫稳定运行的关键。此外,通过Pandas进行数据分析和可视化,可以进一步挖掘数据的价值,为商业决策提供支持。

八、拓展应用

1. 动态数据爬取

对于需要登录或动态加载的网页,可以使用Selenium等工具模拟浏览器操作。

2. 分布式爬虫

在面对大规模数据爬取任务时,可以使用分布式爬虫框架(如Scrapy)来进一步提升效率。

3. 数据库存储

对于大规模数据,可以将数据存储到数据库(如MySQL、MongoDB)中,以便进行更复杂的数据查询和分析。

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

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

相关文章

Deepseek+墨刀,1min快速生成流程图!

想要了解快速了解产品逻辑&#xff0c;可以用ds墨刀快速生成流程图~ deepseek链接&#xff1a;https://www.deepseek.com/ 墨刀在线&#xff1a;https://modao.cc/brand 如何操作呢&#xff1f; 1.打开deepseek&#xff0c;输入以下咒语&#xff0c;让AI用Mermaid语法绘制流…

LangChain4j流式调用、消息注解与会话记忆

我们先用AiService工具类把调用ai大语言模型的代码写出来。因为AiService工具类中整合有记忆、Rag知识库、tools工具等&#xff0c;我们直接配置调用即可。 我用的是qwen-plus模型。 引入依赖&#xff1a; <dependency><groupId>dev.langchain4j</groupId>…

NtfsWriteLog函数分析之OpenAttributeTableDump

第一部分&#xff1a; NtfsWriteLog( IrpContext, Vcb->MftScb, //注意&#xff1a;Vcb->MftScb NULL, OpenAttributeTableDump, …

DCM4CHEE ARCHIVE LIGHT 源代码解析(2)-STOWRS

系列文章目录 DCM4CHEE ARCHIVE LIGHT 源代码解析(1)-前言DCM4CHEE ARCHIVE LIGHT 源代码解析(2)-STOWRS文章目录 系列文章目录概述一、背景资料1、RESTful服务2、传输存储规范3、服务连接策略4、响应消息状态二、业务分析1、对象关系2、项目结构3、业务流程三、代码解析1、w…

Java中间件简介:构建现代软件的“隐形桥梁”

Java中间件简介&#xff1a;构建现代软件的“隐形桥梁” 在软件开发的世界里&#xff0c;中间件&#xff08;Middleware&#xff09;是一个既熟悉又神秘的存在。它不像数据库那样直接存储数据&#xff0c;也不像前端那样与用户交互&#xff0c;但它却是现代软件架构中不可或缺…

Scale AI 的王晓磊带着对整个 AI 行业动态的深入了解加入 Meta

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

冒烟测试概念速解

最近很多人对冒烟测试这个概念发出疑问。那么我就来简单解释一下什么是冒烟测试&#xff0c;以及冒烟测试的由来。 1.冒烟测试的由来 硬件测试的起源&#xff1a;从 “冒烟” 到基础功能验证 在电子工程领域&#xff0c;早期工程师在调试新硬件&#xff08;如电路板、芯片&am…

嵌入式学习笔记——day36-多路IO复用

一、基本概念 &#xff08;服务器多客户端模型&#xff09; 定义&#xff1a; 单线程或单进程同时监测若干个文件描述符是否可以执行IO操作的能力 作用&#xff1a; 应用程序通常需要处理来自多条事件流中的事件&#xff0c;比如我现在用的电脑&#xff0c;需要同时处理键盘鼠…

微服务数据一致性技术解析:从单体到微服务的数据困局

关键词: 微服务数据一致性, 企业应用, 技术架构, 最佳实践 本文基于多位资深架构师在大型互联网公司的实战经验总结&#xff0c;希望能为正在进行微服务改造的团队提供有价值的参考。如果您在实践中遇到问题&#xff0c;欢迎交流讨论&#xff01; 目录 一、引言&#xff1a;从…

华为云Flexus+DeepSeek征文 | 基于华为云ModelArts Studio搭建Chatbox AI聊天助手

华为云FlexusDeepSeek征文 | 基于华为云ModelArts Studio搭建Chatbox AI聊天助手 引言一、ModelArts Studio平台介绍华为云ModelArts Studio简介ModelArts Studio主要特点 二、Chatbox介绍Chatbox简介主要特点 三、安装Chatbox应用下载Chatbox软件安装Chatbox工具 四、开通Deep…

基于cpolar的GPT-SoVITS远程访问实践过程

文章目录 前言1.GPT-SoVITS V2下载2.本地运行GPT-SoVITS V23.简单使用演示4.安装内网穿透工具4.1 创建远程连接公网地址 5. 固定远程访问公网地址 前言 在人工智能技术持续革新之际&#xff0c;语音合成领域涌现出突破性进展。由开发者团队"花儿不哭"研发的GPT-SoVI…

Redis数据结构之HyperLogLog

本文作者没有设置VIP可见&#xff0c;并首发在我的博客&#xff1a;https://blog.liuzijian.com/post/redis-data-structure-hyperloglog.html 目录 1.概述2.常用命令2.1 添加元素2.2 返回基数估算值2.3 合并hyperloglog 3.总结 1.概述 基数统计是一种去重复统计功能的基数估计…

django调用 paramiko powershell 获取cpu 核数

在 Django 应用中使用 paramiko 库通过 SSH 连接到远程服务器并执行命令&#xff08;例如获取 CPU 核数&#xff09;是一个常见的需求。下面是一个如何实现这一过程的步骤指南&#xff1a; 步骤 1: 安装必要的库 首先&#xff0c;确保你的 Django 项目中安装了 paramiko 库。如…

08-Python文件处理

08-Python文件处理 一、打开关闭文件 可以用 file 对象做大部分的文件操作。 file()在python3中已经被废除&#xff0c;使用open()打开文件 open 函数 先用open()打开一个文件&#xff0c;创建一个file 对象&#xff0c;再用相关方法才可以调用它进行读写。 语法 file ob…

增强现实—Multimodal text style transfer for outdoor vision-and-language navigation

&#x1f31f;&#x1f31f; 欢迎来到我的技术小筑&#xff0c;一个专为技术探索者打造的交流空间。在这里&#xff0c;我们不仅分享代码的智慧&#xff0c;还探讨技术的深度与广度。无论您是资深开发者还是技术新手&#xff0c;这里都有一片属于您的天空。让我们在知识的海洋中…

黑马程序员新版Linux学习笔记——第二部分 基础命令

一、Linux目录结构 二、命令基础 三、ls 列目录内容 3.1 命令 3.2 参数 3.3 总结 四、cd 切换工作目录 4.1命令 五、pwd 查看当前工作目录 5.1命令 六、相对路径、绝对路径、特殊路径符 七、mkdir 创建目录命令 7.1命令 八、touch、cat、more 文件操作命令 8.1 touch 8.2c…

日常运维问题汇总-25

76.销售订单交货单状态更新 实务中偶有发生交货已完成&#xff0c;无需开票或开票已经完成&#xff0c;交货单状态为&#xff1a;处理中&#xff0c;且仍然出现在VF04中&#xff0c;如下图所示&#xff1a; 解决方法&#xff1a; T-CODE:VL_COMPLETE,可对错误的DN状态进行更新…

【2025 年】软件体系结构考试试卷-期末考试

2025 年软件体系结构考试试卷 考试学期&#xff1a;2025 考试形式&#xff1a;闭卷 考试时间&#xff1a;120 分钟 年级&#xff1a;______ 专业&#xff1a;软件工程 班级&#xff1a;______ 一、单选题&#xff08;每小题 1.5 分&#xff0c;共 24 分&#xff09; 关于策略…

4.查看、删除数据库

1.显示所有数据库 SHOW DATABASE 2.显示数据库创建语句 SHOW CREAT DATABASE db_name 例如想查看某个数据库是怎样创建的&#xff0c;用的什么字符集啥的。 3.数据库删除语句【慎用】 DROP DATABASE [IF EXISTS] db_name 删除某个数据库之前一定要确定是否进行了备份。

设计模式 - 原型模式

原型模式&#xff08;Prototype&#xff09;&#xff0c;在制造业种通常是指大批量生产开始之前研发出的概念模型&#xff0c;并基于各种参数指标对其进行检验&#xff0c;效果达到了质量要求&#xff0c;即可参照这个原型进行批量生产。即&#xff0c;原型模式可以用对象创建对…