Python爬虫:单线程、多线程、多进程

在这里插入图片描述

前言

在使用爬虫爬取数据的时候,当需要爬取的数据量比较大,且急需很快获取到数据的时候,可以考虑将单线程的爬虫写成多线程的爬虫。下面来学习一些它的基础知识和代码编写方法。

一、进程和线程

进程可以理解为是正在运行的程序的实例。进程是拥有资源的独立单位,而线程不是独立的单位。由于每一次调度进程的开销比较大,为此才引入的线程。一个进程可以拥有多个线程,一个进程中可以同时存在多个线程,这些线程共享该进程的资源,线程的切换消耗是很小的。因此在操作系统中引入进程的目的是更好地使多道程序并发执行,提高资源利用率和系统吞吐量;而引入线程的目的则是减小程序在并发执行时所付出的时空开销,提高操作系统的并发性能。
下面用简单的例子进行描述,打开本地计算机的”任务管理器”如图1所示,这些正在运行的程序叫作进程。如果将一个进程比喻成一个工作,指定10个人来做这份工作,这10个人就是10个线程。因此,在一定的范围内,多线程效率比单线程效率更高。
在这里插入图片描述
图1.任务管理器

二、Python中的多线程与单线程

在我们平时学习的过程中,使用的主要是单线程爬虫。一般来说,如果爬取的资源不是特别大,使用单线程即可。在Python中,默认情况下是单线程的,简单理解为:代码是按顺序依次运行的,比如先运行第一行代码,再运行第二行,依次类推。在前面章节所学习知识中,都是以单线程的形式实践的。
举个例子,批量下载某网站的图片,由于下载图片是一个耗时的操作,如果依然采用单线程的方式下载,那么效率就会特别低,意味着需要消耗更多的时间等待下载。为了节约时间,这时候我们就可以考虑使用多线程的方式来下载图片。
threading模块是Python中专门用来做多线程编程的模块,它对thread进行了封装,使用更加方便。例如需要对写代码和玩游戏两个事件使用多线程进行,案例代码如下。

import threading
import time
# 定义第一个
def coding():for x in range(3):print('%s正在写代码\n' % x)time.sleep(1)
# 定义第二个
def playing():for x in range(3):print('%s正在玩游戏\n' % x)time.sleep(1)
# 如果使用多线程执行
def multi_thread():start = time.time()#  Thread创建第一个线程,target参数为函数命t1 = threading.Thread(target=coding)t1.start()  # 启动线程# 创建第二个线程t2 = threading.Thread(target=playing)t2.start()# join是确保thread子线程执行完毕后才能执行下一个线程t1.join()t2.join()end = time.time()running_time = end - start  print('总共运行时间 : %.5f 秒' % running_time)
# 执行
if __name__ == '__main__':multi_thread()  # 执行单线程

运行结果如图2所示:
图2.多线程运行结果
图2.多线程运行结果
那么执行单线程会消耗多少时间,案例代码如下所示。

import time
# 定义第一个
def coding():for x in range(3):print('%s正在写代码\n' % x)time.sleep(1)
# 定义第二个
def playing():start = time.time()for x in range(3):print('%s正在玩游戏\n' % x)time.sleep(1)end = time.time()running_time = end - startprint('总共运行时间 : %.5f 秒' % running_time)
def single_thread():coding()playing()
# 执行
if __name__ == '__main__':single_thread()  # 执行单线程

运行结果如图3所示:
在这里插入图片描述
图3.单线程运行结果
经过以上多线程和单线程的运行结果,可以看出多线程中写代码和玩游戏是一起执行的,单线程中则是先写代码再玩游戏。从时间上来说,可能只有细微的差距,当执行工作量很大的时候,便会发现多线程消耗的时间会更少,从这个案例中我们也可以知道,当所需要执行的任务并不多的时候,只需要编写单线程即可。

三、单线程改为多线程

以某直播的图片爬取为例,案例代码如下:

import requests
from lxml import etree
import time
import osdirpath = '图片/'
if not os.path.exists(dirpath):os.mkdir(dirpath)  # 创建文件夹header = {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.162 Safari/537.36'
}
def get_photo():url = 'https://www.huya.com/g/4079/'  # 目标网站response = requests.get(url=url, headers=header)  # 发送请求data = etree.HTML(response.text)  # 转化为html格式return datadef jiexi():data = get_photo()image_url = data.xpath('//a//img//@data-original')image_name = data.xpath('//a//img[@class="pic"]//@alt')for ur, name in zip(image_url, image_name):url = ur.replace('?imageview/4/0/w/338/h/190/blur/1', '')title = name + '.jpg'response = requests.get(url=url, headers=header)  # 在此发送新的请求with open(dirpath + title, 'wb') as f:f.write(response.content)print("下载成功" + name)time.sleep(2)if __name__ == '__main__':jiexi()

如果需要修改为多线程爬虫,只需要修改主函数即可,例如创建4个线程进行爬取,案例代码如下所示:

if __name__ == "__main__":threads = []start = time.time()# 创建四个进程for i in range(1, 5):thread = threading.Thread(target=jiexi(), args=(i,))threads.append(thread)thread.start()for thread in threads:thread.join()end = time.time()running_time = end - startprint('总共消耗时间 : %.5f 秒' % running_time)print("全部完成!")  # 主程序

四、图书推荐

在这里插入图片描述

本书介绍了Python3网络爬虫的常见技术。首先介绍了网页的基础知识,然后介绍了urllib、Requests请求库以及XPath、Beautiful Soup等解析库,接着介绍了selenium对动态网站的爬取和Scrapy爬虫框架,最后介绍了Linux基础,便于读者自主部署编写好的爬虫脚本。
本书主要面向对网络爬虫感兴趣的初学者。
在这里插入图片描述

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

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

相关文章

尚硅谷大数据项目《在线教育之离线数仓》笔记001

视频地址:尚硅谷大数据项目《在线教育之离线数仓》_哔哩哔哩_bilibili 目录 P003 P004【数仓概念讲的颇为详细】 P018 P019 P020 P021 P022 P023 P024 P003 时间切片:时间回溯,找回以前的数据。 P004【数仓概念讲的颇为详细】 核心架…

VScode如何设置中文教程

前言:打开VSCode软件,可以看到刚刚安装的VSCode软件默认使用的是英文语言环境,但网上都是vscode中文界面教你怎么设置中文,可能不利于小白阅读,所以重装vscode,手摸手从英文变成中文。 设置为中文 打开VS…

释放马氏距离的力量:用 Python 探索多元数据分析

一、说明 马哈拉诺比斯距离(Mahalanobis Distance)是一种测量两个概率分布之间距离的方法。它是基于样本协方差矩阵的函数,用于评估两个向量之间的相似程度。Mahalanobis Distance考虑了数据集中各个特征之间的协方差,因此比欧氏距…

【833. 字符串中的查找与替换】

来源:力扣(LeetCode) 描述: 你会得到一个字符串 s (索引从 0 开始),你必须对它执行 k 个替换操作。替换操作以三个长度均为 k 的并行数组给出:indices, sources, targets。 要完成第 i 个替换操作: 检查…

ES中倒排索引机制

在ES的倒排索引机制中有四个重要的名词:Term、Term Dictionary、Term Index、Posting List。 Term(词条):词条是索引里面最小的存储和查询单元。一段文本经过分析器分析以后就会输出一串词条。一般来说英文语境中词条是一个单词&a…

nodejs+vue+elementui医院电子病历管理系统5a4x5

此系统任何人都可以使用,哪怕对代码完全不懂,只会电脑的基础操作并且安装这几款软件就可以对本系统进行操作,实现了人员使用方面的自由,不必有过多的限制。 语言 node.js 框架:Express 前端:Vue.js 数据库:…

Http缓存机制

真是一个庞大的话题 // HttpResponse HTTP/1.1 200 OK Content-Type: text/html Content-Length: 1024 Date: Tue, 22 Feb 2022 22:22:22 GMT -->请求返回的最新时间 // (这个时间居然是服务器返回的,那如果发生服务器在DatemaxAge时间之前Response更新了怎么办…

HTTP--Request详解

请求消息数据格式 请求行 请求方式 请求url 请求协议/版本 GET /login.html HTTP/1.1 请求头 客户端浏览器告诉服务器一些信息 请求头名称: 请求头值 常见的请求头: User-Agent:浏览器告诉服务器,我访问你使用的浏览器版本信息 可…

论文复现--关于多视角动作捕捉工具箱 --XRMoCap的研究

分类:动作捕捉 github地址:https://github.com/openxrlab/xrmocap 所需环境: Ubuntu18.04,conda22.9.0,CUDA11.4 目录 环境配置 环境配置 conda create -n XRmocap python3.7 -y conda activate XRmocap# install ffm…

考研408 | 【计算机网络】 传输层

导图 传输层的功能 传输层的两个协议 传输层的寻址与端口 UDP协议 UDP的主要特点 UDP首部格式: UDP校验: TCP协议 TCP协议的特点 TCP报文段首部格式 TCP连接管理 TCP的连接建立 SYN洪泛攻击 TCP的连接释放 TCP可靠传输 序号: 确认&#xff1…

【Vue-Router】使用 prams 路由传参失效

报错信息: [Vue Router warn]: Discarded invalid param(s) “name”, “price”, “id” when navigating. list.json {"data": [{"name": "面","price":300,"id": 1},{"name": "水",&quo…

Algorithem Review 5.2 图论

网络流 设源点为 s s s,汇点为 t t t,每条边 e e e 的流量上限为 c ( e ) c(e) c(e),流量为 f ( e ) f(e) f(e)。割 指对于某一顶点集合 P ⊂ V P \subset V P⊂V,从 P P P 出发指向 P P P 外部的那些原图中的边的集合&a…