当前位置: 首页 > news >正文

Python多线程爬虫为何效率低下?解析原因并提高爬虫速度的方法

目录

  • 一、知识点
    • 二、多线程语法
      • GIL
        • 单线程
        • 多线程
          • 单线程
          • 多线程
      • 最后的惊喜

一、知识点

线程(Thread)也叫轻量级进程,是操作系统能够进行运算调度的最小单位,它被包含在进程之中,是进程中的实际运作单位。线程自己不拥有系统资源,只拥有一点在运行中必不可少的资源,但它可与同属的一个进程的其它线程共享进程所拥有的全部资源。一个线程可以创建和撤销另一个线程,同一进程中的多个线程之间可以并发执行。

二、多线程语法

在Python中实现多线程编程需要用到的就是threading模块中的Thread类,我们来看看最简单的语法,我们首先来一个简单的函数。

def task(num):count = 0for i in range(num):count += 1print(count)nums = [100, 1000, 10000]
for num in nums:task(num)# 100
#1000
#10000

我们用三个子线程分别计算。

import threadingdef task(num):count = 0for i in range(num):count += 1print(count)nums = [100, 1000, 10000]
for num in nums:t = threading.Thread(target=task, args=(num,))t.start()

利用Thread创建线程,target参数接收函数名,args参数接收函数的参数,start方法启动线程。

这里还需要讲解一下join方法,他的作用是让主线程等待,直到该子线程结束。我们来看看加该方法和不加该方法,最终的结果是怎么样的。

import threadingdef task():num = 0for i in range(10000000):num += 1print(num)t = threading.Thread(target=task)
t.start()
print('end')# end
# 10000000import threadingdef task():num = 0for i in range(10000000):num += 1print(num)t = threading.Thread(target=task)
t.start()
t.join()
print('end')# 10000000
# end

GIL

在说概念之前,我们还是以上面的代码为例,分别求单线程和多线程代码运行的时间。

单线程

import timedef task(num):count = 0for i in range(num):count += 1print(count)nums = [1000000, 100000000, 1000000000]
start = time.time()
for num in nums:task(num)
end = time.time()
print(end - start)# 50.44705629348755

多线程

import threading
import timedef task(num):count = 0for i in range(num):count += 1print(count)nums = [1000000, 100000000, 1000000000]
ts = []
start = time.time()for num in nums:t = threading.Thread(target=task, args=(num,))t.start()ts.append(t)for t in ts:t.join()end = time.time()
print(end - start)# 55.022353172302246

你会发现多线程比单线程花费的时间还要更多,这是因为GIL的原因。

GIL的全称是Global Interpreter Lock(全局解释器锁),Python最初的设计理念在于,为了解决多线程之间数据完整性和状态同步的问题,设计为在任意时刻只能由一个线程在解释器中运行。因此Python中的多线程是表面上的多线程(同一时刻只有一个线程),不是真正的多线程。

但是如果是因为GIL的原因,就说多线程无用是不对的,对于IO密集的程序,多线程是要比单线程快的。我们举一个简单的爬虫案例。

单线程
import timedef task(url):s = url.split('_')[-1]time.sleep(int(s)) #这里模拟请求等待urls = ['url_1', 'url_2', 'url_3']
start = time.time()
for url in urls:task(url)
end = time.time()
print(end - start)# 6.013520002365112
多线程
import threading
import timedef task(url):s = url.split('_')[-1]time.sleep(int(s))ts = []
urls = ['url_1', 'url_2', 'url_3']
start = time.time()for url in urls:t = threading.Thread(target=task, args=(url,))t.start()ts.append(t)for t in ts:t.join()end = time.time()
print(end - start)# 3.005527973175049

这时候我们就能看到多线程的优势了,虽然多线程只是在各线程来回切换,但是可以让IO堵塞的时间切换到其他线程做其他的任务,很适合爬虫或者文件的操作。

最后的惊喜

最后这里有准备一些Python的学习资料需要的自取哈

相关文章:

Python多线程爬虫为何效率低下?解析原因并提高爬虫速度的方法

目录 一、知识点二、多线程语法GIL单线程多线程单线程多线程 最后的惊喜 一、知识点 线程(Thread)也叫轻量级进程,是操作系统能够进行运算调度的最小单位,它被包含在进程之中,是进程中的实际运作单位。线程自己不拥有…...

Python 标准方形信号定义(完美实现)

之前我们介绍了如何定义一个标准的正弦信号,这里我们做一下延申,简单说明一下如何定义一个方形函数。 方形信号表达式 square signal = g ( t ) = sign [ sin ⁡ ( 2 π f t +...

[Daimayuan] 走不出的迷宫(C++,图论,DP)

有一个 H H H 行 W W W 列的迷宫(行号从上到下是 1 − H 1−H 1−H,列号从左到右是 1 − W 1−W 1−W),现在有一个由 . 和 # 组成的 H 行 W 列的矩阵表示这个迷宫的构造,. 代表可以通过的空地,# 代表不…...

【LeetCode: 1416. 恢复数组 | 暴力递归=>记忆化搜索=>动态规划 】

🚀 算法题 🚀 🌲 算法刷题专栏 | 面试必备算法 | 面试高频算法 🍀 🌲 越难的东西,越要努力坚持,因为它具有很高的价值,算法就是这样✨ 🌲 作者简介:硕风和炜,…...

centos7查看磁盘io

1.查看所使用到的命令为iostat,centos7没有自带iostat,需要安装一下 2.安装iostat命令 yum -y install sysstat 3.使用iostat命令 iostat %user:表示用户空间进程使用 CPU 时间的百分比 %nice:表示用户空间进程以降低优先级的…...

浅析低代码开发的典型应用构建场景v

在数字经济蓬勃发展的大势之下,企业软件开发人员供给不足、开发速度慢、开发成本高、数字化和智能化成效不明显等问题日益凸出,阻碍了企业的数字化转型。 而近年来,低代码的出现推动了经济社会的全面提效,也成为人才供求矛盾的润…...

3 连续模块(二)

3.5 零极点增益模块 在控制系统设计和分析中,常用的函数包括 传递函数(tf)、零极点(zpk)和状态空间(ss)函数 传递函数(tf):用于表示线性时不变系统的输入输出…...

ElasticSearch 部署及安装ik分词器

ansiable playbook链接: https://download.csdn.net/download/weixin_43798031/87719490 需要注意的点:公司es集群现以三个角色部署分别为 Gateway、Master、Data 简单的理解可以理解为在每台机器上部署了三个es,以端口和配置文件来区分这三…...

汽车充电桩检测设备TK4860C交流充电桩检定装置

TK4860C是一款在交流充电桩充电过程中实时检测充电电量的标准仪器,仪器以新能源车为负载,结合宽动态范围测量技术、电能ms级高速刷新等技术,TK4860C实现充电全过程的累积电能精准计量,相比于传统的预设检定点的稳态计量&#xff0…...

备份和恢复:确保数据安全

备份和恢复:确保数据安全 在计算机领域中,备份和恢复数据对于确保数据安全至关重要。本文将介绍备份策略概述、使用mysqldump进行备份、使用MySQL Enterprise Backup进行备份、恢复数据以及备份和恢复的最佳实践。 备份策略概述 在制定备份策略时&…...

8 DWA(一)

8 DWA DMA简介 DMA(Direct Memory Access)直接存储器存取(可以直接访问32内部存储器,包括内存SRAM,Flash) DMA可以提供外设和存储器或者存储器和存储器之间的高速数据传输,无须CPU干预&#x…...

mysql慢查询日志

概念 MySQL的慢查询日志是MySQL提供的一种日志记录,它用来记录在MySQL中响应时间超过阀值的语句,具体指运行时间超过long_query_time值的SQL,则会被记录到慢查询日志中。long_query_time的默认值为10,意思是运行10秒以上的语句。…...

Sentinel介绍及搭建

分布式流量防护 服务雪崩 服务提供者不可用导致服务调用者也跟着不可用,以此类推引起整个链路中的所有微服务都不可用 分布式流量防护 在分布式系统中,服务之间的相互调用会生成分布式流量。如何通过组件进行流量防护,并有效控制流量&…...

最受信任的低代码平台排行榜

近年来,随着数字化转型的兴起,低代码平台获得了大量关注。它允许用户在几乎没有编码知识的情况下创建应用程序,从而使企业能够简化其流程并提高效率。随着低代码平台的日益流行,要确定哪些平台最可靠、最值得信赖并非易事。在本文…...

Django框架之创建项目、应用并配置数据库

django3.0框架创建项目、应用并配置数据库 创建项目 进入命令行 新建一个全英文的目录 进入目录 输入命令 django-admin startproject project 项目目录层级 查看当前目录层级 tree /f 目录文件说明 创建数据库 做一个学生管理系统做演示,使用navicat创建数据…...

软件测试之基础概念学习篇(需求 + 测试用例 + 开发模型 + 测试模型 + BUG)

文章目录 1. 什么是软件测试2. 软件测试和软件开发的区别3. 软件测试和软件调试的区别4. 什么是需求1)以需求为依据设计测试用例 5. 测试用例是什么6. 什么是 BUG(软件错误)7. 五个开发模型1)瀑布模型2)螺旋模型3&…...

Windows下版本控制器(SVN) - 1、开发中的实际问题+2、版本控制简介

文章目录 基础知识-Windows下版本控制器(SVN)1、开发中的实际问题2、版本控制简介2.1 版本控制[Revision control]2.2 Subversion2.3 Subversion 的优良特性2.4 SVN 的工作原理:2.5 SVN 基本操作 本人其他相关文章链接 基础知识-Windows下版本控制器(SVN) 1、开发中…...

Learning Dynamic Facial Radiance Fields for Few-Shot Talking Head Synthesis 笔记

Learning Dynamic Facial Radiance Fields for Few-Shot Talking Head Synthesis 笔记 摘要 Talking head synthesis is an emerging technology with wide applications in film dubbing, virtual avatars and online education. Recent NeRF-based methods generate more n…...

SpringBoot 项目整合 Redis 教程详解

✅作者简介:2022年博客新星 第八。热爱国学的Java后端开发者,修心和技术同步精进。 🍎个人主页:Java Fans的博客 🍊个人信条:不迁怒,不贰过。小知识,大智慧。 💞当前专栏…...

3ASC25H214 DATX130以力控制为基础的装配应用方面已经形成了一个解决方案

​ 3ASC25H214 DATX130以力控制为基础的装配应用方面已经形成了一个解决方案 ABB的机器人解决方案最终选择了IRB6400机器人 ABB的解决方案 ABB一直都在不断地研究和开发机器人应用的新技术,有一部分研究活动是与大学进行合作的,其中一项是ABB的科学家和…...

从WWDC看苹果产品发展的规律

WWDC 是苹果公司一年一度面向全球开发者的盛会,其主题演讲展现了苹果在产品设计、技术路线、用户体验和生态系统构建上的核心理念与演进脉络。我们借助 ChatGPT Deep Research 工具,对过去十年 WWDC 主题演讲内容进行了系统化分析,形成了这份…...

深入浅出:JavaScript 中的 `window.crypto.getRandomValues()` 方法

深入浅出:JavaScript 中的 window.crypto.getRandomValues() 方法 在现代 Web 开发中,随机数的生成看似简单,却隐藏着许多玄机。无论是生成密码、加密密钥,还是创建安全令牌,随机数的质量直接关系到系统的安全性。Jav…...

ServerTrust 并非唯一

NSURLAuthenticationMethodServerTrust 只是 authenticationMethod 的冰山一角 要理解 NSURLAuthenticationMethodServerTrust, 首先要明白它只是 authenticationMethod 的选项之一, 并非唯一 1 先厘清概念 点说明authenticationMethodURLAuthenticationChallenge.protectionS…...

如何在最短时间内提升打ctf(web)的水平?

刚刚刷完2遍 bugku 的 web 题,前来答题。 每个人对刷题理解是不同,有的人是看了writeup就等于刷了,有的人是收藏了writeup就等于刷了,有的人是跟着writeup做了一遍就等于刷了,还有的人是独立思考做了一遍就等于刷了。…...

LINUX 69 FTP 客服管理系统 man 5 /etc/vsftpd/vsftpd.conf

FTP 客服管理系统 实现kefu123登录,不允许匿名访问,kefu只能访问/data/kefu目录,不能查看其他目录 创建账号密码 useradd kefu echo 123|passwd -stdin kefu [rootcode caozx26420]# echo 123|passwd --stdin kefu 更改用户 kefu 的密码…...

4. TypeScript 类型推断与类型组合

一、类型推断 (一) 什么是类型推断 TypeScript 的类型推断会根据变量、函数返回值、对象和数组的赋值和使用方式,自动确定它们的类型。 这一特性减少了显式类型注解的需要,在保持类型安全的同时简化了代码。通过分析上下文和初始值,TypeSc…...

【Post-process】【VBA】ETABS VBA FrameObj.GetNameList and write to EXCEL

ETABS API实战:导出框架元素数据到Excel 在结构工程师的日常工作中,经常需要从ETABS模型中提取框架元素信息进行后续分析。手动复制粘贴不仅耗时,还容易出错。今天我们来用简单的VBA代码实现自动化导出。 🎯 我们要实现什么? 一键点击,就能将ETABS中所有框架元素的基…...

Vue3中的computer和watch

computed的写法 在页面中 <div>{{ calcNumber }}</div>script中 写法1 常用 import { computed, ref } from vue; let price ref(100);const priceAdd () > { //函数方法 price 1price.value ; }//计算属性 let calcNumber computed(() > {return ${p…...

Qt Quick Controls模块功能及架构

Qt Quick Controls是Qt Quick的一个附加模块&#xff0c;提供了一套用于构建完整用户界面的UI控件。在Qt 6.0中&#xff0c;这个模块经历了重大重构和改进。 一、主要功能和特点 1. 架构重构 完全重写了底层架构&#xff0c;与Qt Quick更紧密集成 移除了对Qt Widgets的依赖&…...

欢乐熊大话蓝牙知识17:多连接 BLE 怎么设计服务不会乱?分层思维来救场!

多连接 BLE 怎么设计服务不会乱&#xff1f;分层思维来救场&#xff01; 作者按&#xff1a; 你是不是也遇到过 BLE 多连接时&#xff0c;调试现场像网吧“掉线风暴”&#xff1f; 温度传感器连上了&#xff0c;心率带丢了&#xff1b;一边 OTA 更新&#xff0c;一边通知卡壳。…...