Python爬虫之多线程加快爬取速度

news2024/11/25 10:25:05

之前我们学习了动态翻页我们实现了网页的动态的分页,此时我们可以爬取所有的公开信息了,经过几十个小时的不懈努力,一共获取了 16万+ 条数据,但是软件的效率实在是有点低了,看了下获取 10 万条数据的时间超过了 56 个小时,平均每分钟才获取 30 条数据。
在这里插入图片描述
在这里插入图片描述

注:软件运行的环境是搬瓦工的虚拟主机,CPU: 2x Intel Xeon , RAM: 1024 MB,Debian 9

软件的运行效率不高,那么时间都花费在什么上面了,爬虫软件本身并不是计算密集型软件,时间大多数花费在与远程主机的通信上了,要想提高软件的运行效率,就要减少等待时间,此时你想到了什么?没错就是多线程,在非计算密集型应用中,使用多线程可以最大程度的节省资源同时提高软件的效率,关于线程的基本应用可以参考前面的文章 python 之进程与线程。

针对多线程的修改

使用多线程后,每个线程执行的应该是不同的任务,如果是相同的任务那就是两个程序而不能说是多线程了。每个线程执行不同的任务「即爬取不同的网页」,需要线程间共享数据「在本程序中需要共享待爬队列、已获取 url 的布隆滤波器等」。因此我们需要多当前的软件进行修改,以使待爬队列和布隆滤波器可以在多个线程之间共享数据。

要想在多线程之间共享待爬队列和布隆滤波器,需要将其从当前的实例属性修改为类属性,以使其可以通过类在多个线程中访问该属性。关于类属性和实例属性可以参考 Python 类和实例 这篇文章。

将待爬队列和布隆滤波器设置为类属性的代码如下:

class Crawler:
    url_queue = Queue()
    bloomfilter = ScalableBloomFilter()
    ...

在使用的过程中通过类名来访问类属性的值,示例代码如下:

def __init__(self, url_count = 1000, url = None):
        if (Crawler.max_url_count < url_count):
            Crawler.max_url_count = url_count

        Crawler.url_queue.put(url)

在多线程中,当前的类属性有多个线程共享,任何一个类属性都有可能被任何线程修改,因此线程之间共享数据最大的危险在于多个线程同时修改一个数据,把数据给修改乱了。由于 Queue 是一个适用于多线程编程的先进先出的数据结构,可以在生产者和消费者线程之间安全的传递消息或数据,因此我们无需对队列进行操作,但是布隆滤波器是非线程安全的数据,此时我们就需要在修改布隆滤波器的地方加上线程锁,以保证在同一时刻只有一个线程能够修改布隆滤波器的数据,代码如下:

def url_in_bloomfilter(self, url):
        if url in Crawler.bloomfilter:
            return True
        return False
    def url_add_bloomfilter(self, url):
        Crawler.lock.acquire()
        Crawler.bloomfilter.add(url)
        Crawler.lock.release()

在所有需要判断 url 是否已经爬取过的地方调用 urlinbloomfilter,当需要向布隆滤波器中添加 url 时调用 urladdbloomfilter 方法,保证布隆滤波器的数据不会被错误修改。

对爬虫类 Crawler 修改完成后,就是真正启动多线程的时候,在 main.py 文件中将代码修改为如下内容:

def main():
    with open('database.conf','r') as confFile:
        confStr = confFile.read()
    conf = json.JSONDecoder().decode(confStr)
    db.init_url(url=conf['mariadb_url'])

    crawler1 = Crawler(1000, url='https://www.szlcsc.com/catalog.html')
    crawler2 = Crawler(1000, url='https://www.szlcsc.com/catalog.html')
    thread_one = threading.Thread(target=crawler1.run)
    thread_two = threading.Thread(target=crawler2.run)
    thread_one.start()
    thread_two.start()
    thread_one.join()
    thread_two.join()

以上代码中首先建立了对数据库的连接,然后创建了两个 Crawler 类的的实例,最后创建了两个线程实例,并启动线程。

修改后的执行结果

在这里插入图片描述
在这里插入图片描述

本次软件开启了两个线程同时运行,同样获取 10 万条数据,一共花费了 29 个小时,平均每分钟获取了 57.5 条数据,相比单线程效率提高了 191.7%,总体来说效率提高还是非常明显的。

在这里插入图片描述

最终在花费 50 小时 30 分钟,从上获取十六万五千条数据后,程序执行完成。

从目录页面可知上共计有十六万七千个元件。程序执行完成后共计获取十六万五千条数据,可以说完成了预期设计目标。

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

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

相关文章

【技巧】Word“只读方式”的设置与取消

如果你担心在阅读Word文档的时候&#xff0c;不小心修改并保存了内容&#xff0c;那就给文档设置“只读方式”吧&#xff0c;这样就算不小心做了修改也不能随意保存。 Word文档的“只读方式”有两种模式&#xff0c;对此不清楚的小伙伴&#xff0c;来看看如何设置和取消吧。 模…

第一次作业

作业内容&#xff1a;1&#xff0c;atd和crond的区别 2&#xff0c;指定在2023/08/26 09&#xff1a;00将时间写入testmail.txt文件中 3&#xff0c;指定在每天凌晨4&#xff1a;00将该时间点之前的系统日志信息备份到个目录下&#xff08;/var/log/messages &#xff09;&…

华为手表开发:WATCH 3 Pro(17)传感器订阅指南针

华为手表开发&#xff1a;WATCH 3 Pro&#xff08;17&#xff09;传感器订阅指南针初环境与设备指南针传感器介绍与说明鸿蒙开发文件夹&#xff1a;文件新增展示的文本标记index.hmlindex.cssindex.js初 希望能写一些简单的教程和案例分享给需要的人 鸿蒙可穿戴开发 环境与设…

二 、Locust自定义用户(场景)

二 、自定义用户&#xff08;场景&#xff09; 一个用户类代表了你系统中的一种用户/场景。当你做一个测试运行时&#xff0c;你指定你想模拟的并发用户的数量&#xff0c;Locust将为每个用户创建一个实例。你可以给这些类/实例添加任何你喜欢的属性&#xff0c;但有一些属性对…

蹭ChatGPT热点有风险,昆仑万维蹭热点被发监管函

‍数据智能产业创新服务媒体——聚焦数智 改变商业要说2023年互联网行业最火爆的概念&#xff0c;ChatGPT绝对当仁不让。国外有微软&#xff0c;国内有百度、阿里、商汤、三六零等&#xff0c;各大互联网巨头都对这个概念青睐有加。众多企业纷纷宣布投身赛道&#xff0c;誓要做…

帮助企业应对不确定性,Serverless时代正在来临

近年来层出不穷的“黑天鹅”事件&#xff0c;让越来越多的企业和组织开始高度关注市场的不确定性。为了增强抵御风险的能力&#xff0c;企业纷纷从开拓业务创新、降低生产成本、提高运营效率、提升用户体验及满意度等方面着手&#xff0c;努力提高自身的核心竞争力。在这样的时…

Java集合——List接口学习总结

一、ArrayList实现类 1. 常用方法 增加&#xff1a;add(int index, E element)删除&#xff1a;remove(int index) remove(Object o)修改&#xff1a;set(int index, E element)查看&#xff1a;get(int index)判断&#xff1a;常用遍历方式&#xff1a;//List集合 遍历&…

2023MathorCup数模C题思路数据代码论文【全网最全分享】

文章目录赛题思路赛题详情参赛建议&#xff08;个人见解&#xff09;选择队友及任务分配问题&#xff08;重要程度&#xff1a;5星&#xff09;2023MathorCup数模C题思路数据论文代码【最新】赛题思路 (赛题出来以后第一时间在CSDN分享) 最新进度在文章最下方卡片&#xff0c;…

Atlassian后Server时代 | Server版vs.数据中心版,二者的区别在哪里?

2024年2月&#xff0c;也就是一年不到&#xff0c;Atlassian将终止对Server产品及插件的所有支持。 此公告发布后&#xff0c;许多用户需要了解怎样的前进方向才是最适合企业的。为此&#xff0c;Atlassian提供了本地部署的数据中心&#xff08;Data Center&#xff09;版以及云…

浅聊MVCC,希望能对你有帮助

浅聊MVCC&#xff0c;希望能对你有帮助&#x1f3cd; 前言 多版本并发控制是数据库管理系统中的一项重要技术&#xff0c;它可以提高数据库的并发性能和可靠性&#xff0c;支持高并发的读写操作&#xff0c;提高数据的安全性&#xff0c;具有重要的应用价值和意义。笔者写此文…

好用的5款国产低代码平台介绍

一、云程低代码平台 云程低代码平台是一款基于springboot、vue.js技术的企业级低代码开发平台&#xff0c;平台采用模型驱动、高低码融合、开放扩展等设计理念&#xff0c;基于业务建模、流程建模、表单建模、报表建模、大屏建模等可视化建模工具&#xff0c;通过拖拉拽零代码方…

深入理解Linux多线程

致前行的人&#xff1a; 昨日渐多&#xff0c;明日愈少&#xff0c;今日还在&#xff0c;不要为成功而努力&#xff0c;要为做一个有价值的人而努力。人生道路上充满了坎坷&#xff0c;谁也不可能一帆风顺。只有在最困难的时刻&#xff0c;才能体会到无助的含义。 目录 1.理解…

ESP32-LORA通信

文章目录好久没更新博客了&#xff0c;今天清明节&#xff0c;写个LORA通信。在此记念在天堂的外婆。祝她安好LORA通信简介一、模块二、使用步骤1.电脑通过USB串口模块联接LORA模块2.ESP32连接LORA通信进行收发通信3.电脑运行调试助手&#xff0c;ESP32运行代码。实现LORA通信测…

3.5 函数的极值与最大值和最小值

学习目标&#xff1a; 我要学习函数的极值、最大值和最小值&#xff0c;我会采取以下几个步骤&#xff1a; 理解基本概念&#xff1a;首先&#xff0c;我会理解函数的极值、最大值和最小值的概念。例如&#xff0c;我会学习函数在特定区间内的最高点和最低点&#xff0c;并且理…

ChatGPT的“N宗罪”?|AI百态(上篇)

序&#xff1a; AI诞生伊始&#xff0c;那是人人欣喜若狂的科技曙光&#xff0c;深埋于哲学、想象和虚构中的古老的梦&#xff0c;终于成真&#xff0c;一个个肉眼可见的智能机器人&#xff0c;在复刻、模仿和服务着他们的造物主——人类。 但科技树的点亮&#xff0c;总会遇到…

解决python中import导入自己的包呈现灰色 无效的问题

打开File–> Setting—> 打开 Console下的Python Console&#xff0c;把选项&#xff08;Add source roots to PYTHONPAT&#xff09;点击勾选上。 右键点击需要导入的工作空间文件夹&#xff0c;找到Mark Directory as 选择Source Root。 另外&#xff0c;Python中的…

自然语言处理(六): Deep Learning for NLP: Feedforward Networks

目录 1. Deep Learning 1.2 Feed-forward NN 1.3 Neuron 1.4 Matrix Vector Notation 矩阵向量表示法 1.5 Output Layer 1.6 Learning from Data 1.7 Regularisation 正则化 1.8 Dropout 2. Applications in NLP 2.1 Topic Classification 2.2 Topic Classification…

如何在 Linux 中使用 Chage 命令,修改Linux系统用户密码更改策略

Chage是一个用于修改Linux系统用户密码更改策略的命令行工具。在本文中&#xff0c;我们将介绍如何在Linux系统中使用Chage命令。 检查用户密码过期信息 使用Chage命令可以检查用户密码更改策略和过期信息。要检查特定用户的密码过期信息&#xff0c;可以使用以下命令&#x…

【区块链】走进web3的世界-gas费用

气体单位用于衡量在以太坊上执行交易所需的计算量。由于每笔交易都需要一些计算资源来执行&#xff0c;因此需要一笔费用&#xff0c;通常称为Gas fee或Transaction fee 。 汽油费以以太坊的本地货币——ether或ETH支付。汽油费的计算方式在伦敦升级前后略有不同。 注意&#…

进程间通信之共享内存

共享内存一. 什么是共享内存二. 共享内存有关函数1.获取key2.打开创建共享内存对象 - shmget3.映射空间地址 - shmat4.取消映射 - shmdt5.删除共享内存对象 - shmctl三. 实例四. 注意事项1.查看当前系统的共享内存2.当两个进程间ftok参数不一样时,shmid也不一样,共享内存不是同…