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

之前我们学习了动态翻页我们实现了网页的动态的分页,此时我们可以爬取所有的公开信息了,经过几十个小时的不懈努力,一共获取了 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 分钟,从上获取十六万五千条数据后,程序执行完成。

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Vue——组件基础

目录 定义一个组件​ 使用组件​ 传递 props​ 监听事件​ 通过插槽来分配内容​ 动态组件​ DOM 模板解析注意事项​ 大小写区分​ 闭合标签​ 元素位置限制​ 组件允许我们将 UI 划分为独立的、可重用的部分&#xff0c;并且可以对每个部分进行单独的思考。在实际应…

如何用 YonBuilder 构建线索管理应用

加速企业数智营销&#xff1a;如何用 YonBuilder 构建线索管理应用 如何用 YonBuilder 低代码开发线索管理应用&#xff1f; 线索管理是指通过各种渠道收集、筛选、打分、分配、跟进和培育潜在客户的信息&#xff0c;以便将其转化为成交客户的过程。 通过数智化手段实现良好…

00后整顿职场,我直呼太卷了....

内卷的来源 内卷最早的“出处”是几张名校学霸的图片。 大学生们刷爆朋友圈的几张“内卷”图片是这样的&#xff1a;有的人骑在自行车上看书&#xff0c;有的人宿舍床上铺满了一摞摞的书&#xff0c;有的人甚至边骑车边端着电脑写论文。这些图片最早在清华北大的学霸之间流传。…

C++学习从基础到高阶(基于黑马程序员教程)

视频链接&#xff1a;黑马程序员匠心之作|C教程从0到1入门编程,学习编程不再难&#xff08;52个小时&#xff09; C语言中文网&#xff1a;http://c.biancheng.net/cplus/ Visual Studio 2022 下载地址&#xff1a;https://visualstudio.microsoft.com/zh-hans/downloads/ Visu…

JavaWeb - Web网站的组成,工作流程以及开发模式

一. Web Web&#xff1a;全球广域网&#xff0c;也称玩万维网(www Wrold Wide Web)&#xff0c;就是能够通过浏览器访问的网站学习Web开发&#xff0c;其实就是要使用Java这门语言来开发这样的Web网站&#xff0c;这也是现在Java语言最主流的企业级应用方式。使用Java语言开发…

PERSIANN 降雨数据使用教程

一、前言PERSIANN&#xff0c;“使用人工神经网络从遥感信息中估算降水”&#xff0c;是一种基于卫星的降水检索算法&#xff0c;可提供近乎实时的降雨信息。该算法使用来自全球地球同步卫星的红外 (IR) 卫星数据作为降水信息的主要来源。 红外图像的降水基于云顶温度和降水率之…

一位腾讯在职7年测试工程师的心声...

作为一个在腾讯工作7年的测试工程师&#xff0c;今天就来聊聊腾讯工作压力到底从何而来。 压力的开始&#xff1a;时间回到7年前&#xff0c;我人生中的第一份实习工作&#xff0c;是在腾讯公司做一个自动化测试工程师。当时的我可谓意气风发&#xff0c;想要大干一场&#xf…

工厂模式白话 - 3种都有哦

前言 工厂模式&#xff08;Factory Pattern&#xff09;里所谓的“工厂”和现实生活中的工厂一样 主要作用都是生产产品 像食品厂、服装厂、汽车厂生产吃的、穿的、开的 设计模式里的工厂则是生产对象 划分 工厂模式可分为简单工厂、工厂方法、抽象工厂3种 有啥不同呢&a…

PyTorch笔记

Tensor torch中的Tensor是一种数据结构&#xff0c;使用上与Python的list、numpy的array、ndarray等数据结构类似&#xff0c;可以当成一个多维数组来用。 数学上对张量有特定定义&#xff0c;但通常理解为多维数组即可。 生成Tensor&#xff1a;torch包中提供了直接生成Tens…

【微信小程序】初识微信小程序组件

作者简介&#xff1a;一名C站萌新&#xff0c;前来进行小程序的前进之路博主主页&#xff1a;大熊李子&#x1f43b; 一、组件的创建与引用 1.1 创建组件 在项目的根目录中&#xff0c;鼠标右键&#xff0c;创建 components -> test 文件夹在新建的 components -> test…

十分钟验证一个轻量化车联网解决方案

智能网联汽车在车联网的应用上&#xff0c;通常是以智能传感器、物联网、GIS技术为基础&#xff0c;结合大数据、人工智能技术&#xff0c;通过OT&#xff08;Operation tecnology&#xff09;和IT&#xff08;information tecnology&#xff09;融合的方式&#xff0c;实现智能…

2.3 连续性随机变量

思维导图&#xff1a; 学习目标&#xff1a; 我会按照以下步骤学习连续型随机变量&#xff1a; 复习概率论的基础知识&#xff0c;包括概率、期望、方差等概念和公式&#xff0c;以及离散型随机变量的概率分布函数和概率质量函数的概念和性质。 学习连续型随机变量的概念和性…

学生信息管理系统(student information manage system, SIMS)

一、前言 本项目为学生信息管理系统&#xff0c;使用C语言编写。 ★★★项目详见本人gitee仓库&#xff0c;地址 https://gitee.com/omnipotent-brother/student-information-manage-system.git ★★★ 二、项目介绍 开发环境&#xff1a; 基于windows 11系统下的Visual Studio…

YC-A11(原创)基于springboot,vue网上商城

绪论 课题的开发背景 随着计算机和网络的快速发展&#xff0c;并且越来越普及&#xff0c;互联网日益成为人们收集信息常用渠道&#xff0c;电子商务开始流行&#xff0c;一种全新的理念不断形成并且快速发展&#xff0c;像国内电商巨头淘宝、京东、苏宁易购、唯品会等电商平台…

【JavaScript】2.JavaScript函数

JavaScript 函数 1. 函数的概念 函数&#xff1a;就是封装了一段可被重复调用执行的代码块 通过此代码块可以实现大量代码的重复使用 2. 函数的使用 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta na…

前馈PID控制(热交换器/反应釜温度控制)

如何利用PID进行温度控制请参看下面博客文章: 博途PID 1200/1500PLC PID_Compact比例作用权重b微分作用权重c解读(PI-D控制器 I-PD控制器)_RXXW_Dor的博客-CSDN博客很多人会问PLC自带的PID指令和我们自己设计的PID有什么区别,这个问题要看你和什么PID控制器作对比,PID负反…

NDK RTMP直播客户端二

在之前完成的实战项目【FFmpeg音视频播放器】属于拉流范畴&#xff0c;接下来将完成推流工作&#xff0c;通过RTMP实现推流&#xff0c;即直播客户端。简单的说&#xff0c;就是将手机采集的音频数据和视频数据&#xff0c;推到服务器端。 接下来的RTMP直播客户端系列&#xff…

Redis用于全局ID生成器、分布式锁的解决方案

全局ID生成器 每个店铺都可以发布优惠卷 当用户抢购时&#xff0c;就会生成订单并保存到tb_voucher_order这张表中&#xff0c;而订单表如果使用数据库自增id就存在一些问题&#xff1a; 1.id的规律性太明显 2.受单表数据量的限制 全局ID生成器&#xff0c;是一种在分布式系…

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

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

线段树笔记草稿

一个左节点u << 1和右节点u << 1 | 1 的证明 区间修改部分 1.批量等值修改 前提条件 是要区间修改&#xff0c;区间查询&#xff0c;且修改操作修改的值是相同的 情景 一般是要对一个数组执行k次操作&#xff0c;每次改变其中一个区间内所有元素的值&#x…