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 - start
    print('总共运行时间 : %.5f 秒' % running_time)
def single_thread():
    coding()
    playing()
# 执行
if __name__ == '__main__':
    single_thread()  # 执行单线程

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

三、单线程改为多线程

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

import requests
from lxml import etree
import time
import os

dirpath = '图片/'
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 data

def 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 - start
    print('总共消耗时间 : %.5f 秒' % running_time)
    print("全部完成!")  # 主程序

文末免费送书:Python网络爬虫入门到实战

本书介绍了Python3网络爬虫的常见技术。首先介绍了网页的基础知识,然后介绍了urllib、Requests请求库以及XPath、Beautiful Soup等解析库,接着介绍了selenium对动态网站的爬取和Scrapy爬虫框架,最后介绍了Linux基础,便于读者自主部署编写好的爬虫脚本。本书所有代码和相关素材可以到GitHub下载获取,地址为https://github.com/sfvsfv/Crawer。
本书主要面向对网络爬虫感兴趣的初学者。。
在这里插入图片描述

抽奖方式: 评论区随机抽取3位小伙伴免费送出!
参与方式: 关注博主、点赞、收藏、评论区评论“人生苦短,我用Python!”(切记要点赞+收藏,否则抽奖无效,每个人最多评论三次!)
活动截止时间: 2024-3-04 20:00:00
京东: 购买链接传送门

😄😄😄名单公布方式: 下期活动开始将在评论区和私信一并公布,中奖者请三天内提供信息😄😄😄

本书内容
本书通过简单易懂的案例,讲解Python语言的爬虫技术。全书共分为8章,第1章为网页的内容,第2~7章为爬虫的内容,第8章为Linux基础。
第1章:介绍了HTML和CSS的基础知识,虽然本章并不是直接与爬虫相关,但它是学习爬虫技术的基础。对于已经掌握基本网页基础的读者,可以选择跳过该章。
第2章:正式进入爬虫技术的学习阶段,这一章介绍了最基本的两个请求库(urllib和Requests),有知识点的讲解,也有实战案例的讲解。
第3章:本章对正则表达式做了详细的描述,同时有案例的实践。学完本章就可以掌握最基本的爬虫技术了。
第4章:主要介绍XPath解析库,配有实际的案例进行讲解,以帮助读者加深理解和巩固。
第5章:主要介绍另一个解析库Beautiful Soup,它在提取数据中也很方便,对相关知识点以及实际的案例都有所讲解。XPath和Beautiful Soup可以使信息的提取更加方便、快捷,是爬虫必备利器。
第6章:主要介绍selenium自动化测试。现在越来越多的网站内容是经过 JavaScript 渲染得到的,而原始 HTML 文本可能不包含任何有效内容,使用模块selenium实现模拟浏览器进行数据爬取是非常好的选择。
第7章:在大规模数据的爬取中,不太用得上基础模块,Scrapy 是目前使用最广泛的爬虫框架之一,本章介绍了Scrapy爬虫框架的详细搭建和实践。针对数据存储过程部分使用的MySql数据库,整章有多个实际的案例,以帮助读者加深理解和巩固。
第8章:主要介绍了Linux的基础知识点,以帮助读者能够在服务器部署脚本。
相关资源
本书所有代码和相关素材可以到GitHub下载获取,地址为https://github.com/sfvsfv/Crawer。关于代码的实用性需要声明:所有代码都是笔者在写书阶段编写的,如果有部分爬虫脚本失效,有可能是网站的结构发生了变化。希望读者在阅读本书的过程中,以学习笔者所介绍的方法为主。
Python网络爬虫入门到实战致谢
本书的撰写与出版得益于同行众多同类教程的启发,以及陈姗姗老师和同伴周培源的帮助,在此深表感谢。同时也感谢一路走来支持笔者的读者。由于本人水平有限,书中难免有不妥之处,诚挚期盼专家和广大读者批评指正。

在这里插入图片描述

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

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

相关文章

【沐风老师】3DMAX快速布尔插件使用方法讲解

3DMAX快速布尔插件FastBool使用教程 3DMAX快速布尔插件FastBool,是一个基于布尔运算的小型但功能非常强大的插件。工作方便快捷。 【版本要求】 3dMax2017-2024(不仅限于此范围) 【安装方法】 该插件无需安装,使用时直接拖动插件…

使用 Verilog 做一个可编程数字延迟定时器 LS7211-7212

今天的项目是在 Verilog HDL 中实现可编程数字延迟定时器。完整呈现了延迟定时器的 Verilog 代码。 所实现的数字延迟定时器是 CMOS IC LS7212,用于生成可编程延迟。延迟定时器的规格可以在这里轻松找到。基本上,延迟定时器有 4 种操作模式:…

深度学习目标检测】二十、基于深度学习的雾天行人车辆检测系统-含数据集、GUI和源码(python,yolov8)

雾天车辆行人检测在多种场景中扮演着至关重要的角色。以下是其作用的几个主要方面: 安全性提升:雾天能见度低,视线受阻,这使得驾驶者和行人在道路上的感知能力大大降低。通过车辆行人检测技术,可以在雾天条件下及时发现…

振弦采集仪在桥梁岩土工程中的应用与效果评价

振弦采集仪在桥梁岩土工程中的应用与效果评价 河北稳控科技振弦采集仪是一种用于结构动力测试的仪器,也可以应用于桥梁和岩土工程中。其主要作用是通过测量结构的振动特性,分析结构的动态行为,评估结构的健康状况和性能。 在桥梁工程中&…

【非比较排序】计算排序算法

目录 CountSort计数排序 整体思想 图解分析 代码实现 时间复杂度&优缺分析 CountSort计数排序 计数排序是一种非比较排序,不需要像前面的排序一样去比较。 计数排序的特性总结: 1. 计数排序在数据范围集中时,效率很高,但…

【element+vue】点击加号增加一行,点击减号删除一行

代码实现&#xff1a; 页面部分&#xff1a; vueelement 备注&#xff1a;v-if “i>0” &#xff08;保证第一行不出现减号&#xff09; <div v-for"(item,i) in studentList"><el-form-item label"学生:" prop"name"><el-i…

基于Java SSM框架实现家庭食谱管理系统项目【项目源码+论文说明】计算机毕业设计

基于java的SSM框架实现家庭食谱管理系统演示 摘要 本论文主要论述了如何使用JAVA语言开发一个家庭食谱管理系统 &#xff0c;本系统将严格按照软件开发流程进行各个阶段的工作&#xff0c;采用B/S架构&#xff0c;面向对象编程思想进行项目开发。在引言中&#xff0c;作者将论…

智慧公厕:打造智慧城市环境卫生新标杆

随着科技的不断发展和城市化进程的加速推进&#xff0c;智慧城市建设已经成为各地政府和企业关注的焦点。而作为智慧城市环境卫生管理的基础设施&#xff0c;智慧公厕的建设和发展也备受重视&#xff0c;被誉为智慧城市的新标杆。本文以智慧公厕源头厂家广州中期科技有限公司&a…

Ubuntu22.04环境下载安装中文搜狗输入法

0、查看CPU系统架构 确定架构后&#xff0c;下载对应的安装包&#xff0c;否则无法正常安装应用程序 1、进入搜狗拼音输入法官网&#xff0c;下载搜狗输入法 搜狗输入法-首页搜狗拼音输入法官网下载&#xff0c;荣获多个国内软件大奖的搜狗拼音输入法是一款打字更准、词库更大…

2024年【安全员-A证】考试及安全员-A证模拟考试

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 安全员-A证考试根据新安全员-A证考试大纲要求&#xff0c;安全生产模拟考试一点通将安全员-A证模拟考试试题进行汇编&#xff0c;组成一套安全员-A证全真模拟考试试题&#xff0c;学员可通过安全员-A证模拟考试全真模…

【Python数据分析系列】多个dataframe写入同一个excel文件(案例源码)

一、引言 将多个DataFrame写入同一个excel文件中&#xff0c;每个DataFrame作为一个sheet&#xff0c;可以使用pandas库中的ExcelWriter类。这个类可以在一个Excel文件中创建多个sheet&#xff0c;并将不同的数据写入这些sheet中。本文演示如何将多个DataFrame写入同一个CSV文件…

抖音视频评论抓取软件|视频批量下载

抖音视频评论采集软件是一款基于C#开发的高效、便捷的工具&#xff0c;旨在为用户提供全面的数据采集和分析服务。该软件不仅支持通过关键词进行搜索抓取&#xff0c;还能够通过分享链接进行单个视频的抓取和下载&#xff0c;让用户轻松获取抖音视频评论数据。 &#x1f50d; …

uniapp 安卓GPS定位原生插件

插件介绍 安卓GPS定位插件&#xff0c;支持获取定位权限&#xff0c;获取上一次的定位信息&#xff0c;持续定位监听&#xff0c;取消定位监听&#xff0c;可返回详细街道信息 插件地址 安卓GPS定位插件&#xff0c;支持持续定位监听&#xff0c;支持返回详细街道信息 - DCl…

springboot003图书个性化推荐系统的设计与实现(源码+调试+LW)

项目描述 临近学期结束&#xff0c;还是毕业设计&#xff0c;你还在做java程序网络编程&#xff0c;期末作业&#xff0c;老师的作业要求觉得大了吗?不知道毕业设计该怎么办?网页功能的数量是否太多?没有合适的类型或系统?等等。今天给大家介绍一篇基于SpringBoot的图书个…

web安全学习笔记【17】——信息打点(7)

信息打点-APP资产&知识产权&应用监控&静态提取&动态抓包&动态调试 #知识点&#xff1a; 1、业务资产-应用类型分类 2、Web单域名获取-接口查询 3、Web子域名获取-解析枚举 4、Web架构资产-平台指纹识别 ------------------------------------ 1、开源-CMS指…

切比雪夫(最小区域法)球拟合算法

欢迎关注更多精彩 关注我&#xff0c;学习常用算法与数据结构&#xff0c;一题多解&#xff0c;降维打击。 本期话题&#xff1a;切比雪夫&#xff08;最小区域法&#xff09;球拟合算法 相关背景和理论 点击前往 主要介绍了应用背景和如何转化成线性规划问题 球拟合输入和输…

【Python笔记-设计模式】命令模式

一、说明 命令模式是一种行为设计模式&#xff0c;旨在对命令的封装&#xff0c;根据不同的请求将方法参数化、延迟请求执行或将其放入队列中&#xff0c;且能实现可撤销操作。 (一) 解决问题 将请求发送者和接受者解耦&#xff0c;请求发送者只需知道如何发送请求&#xff…

【力扣hot100】刷题笔记Day14

前言 又是新的一周&#xff0c;快乐的周一&#xff0c;快乐地刷题&#xff0c;今天把链表搞完再干活&#xff01; 114. 二叉树展开为链表 - 力扣&#xff08;LeetCode&#xff09; 前序遍历 class Solution:def flatten(self, root: Optional[TreeNode]) -> None:if not r…

Ubontu更换软件包源库来提高下载速度

对于 apt-get update 运行缓慢的问题&#xff0c;您可以尝试更换软件包源库来提高下载速度。在 Debian 系统中&#xff0c;可以通过编辑 /etc/apt/sources.list 文件来更改软件包源 1、打开 /etc/apt/sources.list 文件&#xff1a;使用文本编辑器&#xff08;例如 vi、nano 或…

Linux使用Docker部署Traefik容器并实现远程访问管理界面

文章目录 一、Zotero安装教程二、群晖NAS WebDAV设置三、Zotero设置四、使用公网地址同步Zotero文献库五、使用永久固定公网地址同步Zotero文献库 Zotero 是一款全能型 文献管理器,可以 存储、管理和引用文献&#xff0c;不但免费&#xff0c;功能还很强大实用。 ​ Zotero 支…