《Python网络爬虫基础教程》 课件-第6章 提升网络爬虫速度_第1页
《Python网络爬虫基础教程》 课件-第6章 提升网络爬虫速度_第2页
《Python网络爬虫基础教程》 课件-第6章 提升网络爬虫速度_第3页
《Python网络爬虫基础教程》 课件-第6章 提升网络爬虫速度_第4页
《Python网络爬虫基础教程》 课件-第6章 提升网络爬虫速度_第5页
已阅读5页,还剩61页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第6章提升网络爬虫速度《Python网络爬虫基础教程》学习目标/Target了解网络爬虫速度的提升方案,能够说出多线程和协程的区别熟悉多线程爬虫的运行流程,能够归纳多线程爬虫的运行流程掌握多线程爬虫的实现技术,能够使用threading和queue模块实现多线程爬虫熟悉协程爬虫的运行流程,能够归纳协程爬虫的运行流程掌握协程爬虫的实现技术,能够使用asyncio和aiohttp库实现协程爬虫章节概述/Summary网络环境不稳定导致如下情况出现:当基于单线程的网络爬虫采集网页数据时,如果有一个网页的响应速度慢或者网页一直处于加载状态中,那么网络爬虫需要等待该网页加载完才能继续采集。这显然降低了网络爬虫的运行速度。为解决此问题,提升网络爬虫的运行速度,我们可以在网络爬虫程序中加入多线程、协程等技术,实现同时抓取或解析多个网页的数据。目录/Contents6.16.26.3网络爬虫速度提升方案多线程爬虫协程爬虫6.4实践项目:采集黑马头条的评论列表网路爬虫速度提升方案6.1了解网络爬虫速度的提升方案,能够说出多线程和协程的区别学习目标6.1网络爬虫速度提升方案影响网络爬虫速度的因素主要是网络I/O操作,原因在于网络I/O操作的速度赶不上CPU的处理速度。网络I/O操作可以理解为在网络协议的支持下,一个主机通过网络与其他主机进行数据传输的过程。例如下载图片就是一个网络I/O操作。试想一下,网络爬虫正在执行下载大量图片的任务,它在下载图片的过程中会一直处于阻塞状态。这会导致CPU当前处于空闲状态,直到下载完图片后才能让CPU调度其他任务。这就造成了CPU的浪费。在Python中,提升网络爬虫程序运行速度主要有三种方案,分别是多进程、多线程和协程。6.1网络爬虫速度提升方案多进程多线程协程多进程可以利用多核CPU,将任务运行到不同的CPU上,实现同时执行多个任务。进程的数量取决于计算机CPU的处理器个数。6.1网络爬虫速度提升方案多进程多线程协程多线程是以并发(一个时间段内发生若干事情的情况)的方式执行任务的,它不能实现真正地同时执行多个任务,而是通过线程的快速切换提升程序的运行速度。6.1网络爬虫速度提升方案多进程多线程协程协程是以异步并发的方式执行任务的,由于协程无需系统内核的上下文切换,所以程序在执行过程中可以避免大量的等待时间。6.1网络爬虫速度提升方案6.1网络爬虫速度提升方案网络爬虫如何选择多进程、多线程和协程呢?多进程适用于CPU密集型的代码,如循环处理、大量的密集并行计算等;多线程适用于I/O密集型的代码,如文件处理、网络交互等;协程适用于大量不需要CPU的操作(如网络I/O)。结合多线程、多进程和多协程的特点和用途,一般会选择多线程和协程技术开发网络爬虫程序。6.1网络爬虫速度提升方案多学一招进程是系统进行资源分配的最小单位,它拥有自己的内存空间,每个进程之间的数据不共享。线程是系统调度执行的最小单位,它不能独立存在,必须依赖进程,每个线程之间的数据可以共享。协程是用户态的轻量级线程,调度由用户控制,拥有自己的寄存器上下文和栈。进程、线程和协程多线程爬虫6.2熟悉多线程爬虫的运行流程,能够归纳多线程爬虫的运行流程学习目标6.2.1多线程爬虫流程分析6.2.1多线程爬虫流程分析多线程爬虫会将多线程技术运用在抓取网页和解析网页上,它的运行流程图如右所示。6.2.1多线程爬虫流程分析(1)构建一个网址队列,用于存放网络爬虫待抓取数据的所有网址。(2)开启多个线程抓取网页。(3)将抓取到的网页源码存储到网页源码队列中。(4)开启多个线程对网页源码队列中的网页数据进行解析。(5)将解析之后的数据存储到网页数据队列中。(6)将网页数据队列中的数据进行存储。多线程爬虫的运行流程如下。掌握多线程爬虫的实现技术,能够使用threading和queue模块实现多线程爬虫学习目标6.2.2多线程爬虫实现技术6.2.2多线程爬虫实现技术由于线程具有独立运行、状态不可预测、执行顺序随机的特点,当多个线程同时访问同一份资源时,容易导致程序产生不可预料的结果,为此多线程爬虫使用队列管理网址或网页源码。Python中分别提供了支持多线程和队列的内置模块threading和queue。

threading模块模块threading中定义了Thread类,该类专门用于管理线程。若希望在程序中创建一个线程(也称子线程),需要实例化一个Thread类的对象。6.2.2多线程爬虫实现技术Thread(group=None,target=None,name=None,args=(),kwargs={},*,daemon=None)group:必须为None,目前未实现,是为以后的扩展功能保留的预留参数。target:表示子线程的功能函数,用于为子线程分派任务。name:线程的名称,默认由“Thread-N”形式组成,其中N为十进制数。args:target指定函数的位置参数。kwargs:target指定函数的关键字参数。daemon:表示是否将线程设为守护线程(在后台运行的一类特殊线程,用于执行特定的任务)6.2.2多线程爬虫实现技术classMyThread(Thread):def__init__(self,num):super().__init__()='线程'+str(num)defrun(self):message=+'运行'print(message)thread_two=MyThread(1)方式二fromthreadingimportThread#任务函数deftask():print('线程运行')thread_one=Thread(target=task)

方式一Python创建线程的方式。

Queue模块Python的queue模块中提供了3个表示同步的、线程安全的队列的类,这些队列类包括Queue类、LifoQueue类和PriorityQueue类,队列是线程间常用的交换数据的形式。6.2.2多线程爬虫实现技术fromqueueimportQueuequeue_object=Queue(10)foriinrange(4):queue_object.put(i)whilenotqueue_object.empty():print(queue_object.get())Queue类Queue类表示一个基本的FIFO(FirstInFirstOut)队列,即先进先出,也就是说先存入队列中的元素先取出来。

Queue模块6.2.2多线程爬虫实现技术fromqueueimportLifoQueuelifo_queue=LifoQueue()foriinrange(4):lifo_queue.put(i)whilenotlifo_queue.empty():print(lifo_queue.get())LifoQueue类LifoQueue类表示一个LIFO(LastinFirstOut)队列,与栈类似,即后进先出,也就是说后存入队列中的元素先取出来。

Queue模块6.2.2多线程爬虫实现技术fromqueueimportPriorityQueueclassJob:def__init__(self,level,description):self.level=levelself.description=descriptionreturndef__lt__(self,other):returnself.level<other.levelpriority_queue=PriorityQueue()priority_queue.put(Job(5,'中级别工作'))priority_queue.put(Job(10,'低级别工作'))priority_queue.put(Job(1,'重要工作'))whilenotpriority_queue.empty():next_job=priority_queue.get()print('开始工作:',next_job.description)PriorityQueue类PriorityQueue类表示优先级队列,它按级别顺序取出元素,级别最低的最先取出。6.2.2多线程爬虫实现技术为了便于管理队列的元素,Queue类中提供了一些常用方法,这些方法的说明如下表所示。方法说明qsize()返回队列的大小empty()如果队列为空,返回True,否则为Falsefull()如果队列满了,返回True,否则为Falseget()从队头获取并删除第一个元素put()将一个元素放入队列末尾join()阻塞线程,直至队列中所有元素被处理完task_done()在完成一项工作之后,task_done()函数向任务已经完成的队列发送一个信号get_nowait()立即取出一个元素,无需额外等待put_nowait()立即放入一个元素,无需额外等待掌握多线程爬虫的实现技术,能够使用多线程技术抓取黑马程序员论坛网站数据学习目标6.2.3多线程爬虫基本示例6.2.3多线程爬虫基本示例以黑马程序员论坛网站为例,带领大家一起使用threading和queue模块实现多线程爬虫,并让多线程爬虫采集Python技术交流版块中所有帖子的文章标题、文章作者、文章链接以及发布时间。案例需求6.2.3多线程爬虫基本示例案例步骤案例分析定义HeiMa类构造请求网址定义数据存储方法定义提取方法定义抓取方法6.2.3多线程爬虫基本示例执行代码运行代码后,可以看到在代码文件同级目录下添加了一个新的文件thread-heima.json,该文件中存储了Python技术交流版块中所有贴子的文章标题、文章作者、文章链接和发布时间。[单击查看源码]熟悉多线程爬虫性能分析,能够计算出多线程爬虫耗时时间学习目标6.2.4多线程爬虫性能分析6.2.4多线程爬虫性能分析if__name__=="__main__":begin_page=int(input("请输入起始页码:"))end_page=int(input("请输入结束页码:"))s_time=time.time()heima_forum(begin_page,end_page)e_time=time.time()print(f'总用时:{e_time-s_time}秒')在4.6节中,编写了一个单线程爬虫采集Python+人工智能技术交流版块中所有贴子的文章标题、文章作者、文章链接和发布时间。使用time模块计算此爬虫运行时间。运行代码,在控制台中输入起始页码为1,结束页码为70,按下回车后输出的结果如下。总用时:17.572004795074463秒6.2.4多线程爬虫性能分析if__name__=='__main__':s_time=time.time()heima=HeiMa()heima.run()e_time=time.time()print(f'总用时:{e_time-s_time}秒')在6.2.3小节项目的main语句中添加网络爬虫耗时计算的代码。运行代码,在控制台中输入起始页码为1,结束页码为70,按下回车后输出的结果如下。总用时:3.3751931190490723秒6.2.4多线程爬虫性能分析通过比较单线程爬虫和多线程爬虫耗费的时长可知,在相同的条件下,多线程的性能优于单线程爬虫的性能。协程爬虫6.3熟悉协程爬虫的运行流程,能够归纳协程爬虫的运行流程学习目标6.3.1协程爬虫流程分析6.3.1协程爬虫流程分析由于协程的切换不像多线程调度那样耗费资源,所以我们不用严格限制协程的数量,它的运行流程图如右所示。(1)构建一个网址列表,由于要为每个网址分配一个协程,所以需要准备一个网址列表。(2)为每个网址分配一个协程,每个协程负责先抓取源码,再对这些源码进行解析并从中提取出目标数据。(3)将提取的目标数据存储到数据列表中。(4)遍历步骤(3)的数据列表,将取出的数据进行存储。协程爬虫的运行流程如下。6.3.1协程爬虫流程分析掌握协程爬虫的实现技术,能够使用asyncio和aiohttp库实现协程爬虫学习目标6.3.2协程爬虫实现技术Python中提供了支持协程的内置库asyncio,该库经常会与第三方库aiohttp配合使用,以帮助开发人员快速实现协程爬虫。另外,我们也可以使用aiofiles库将爬虫解析完的数据实现异步写入。6.3.2协程爬虫实现技术

asyncio库importasyncioasyncdefmain(): #定义协程

print('hello')awaitasyncio.sleep(1)#阻塞等待1秒

print('world')在asyncio库中,async/await

关键字用于定义协程,其中关键字async位于关键字def的前面,表明async修饰的函数是一个协程函数,而不是普通函数;关键字await位于协程函数内部,该关键字的后面需要跟着可等待对象(协程对象、协程任务和Future类的对象),表明当前协程会被挂起并主动让出执行权。6.3.2协程爬虫实现技术

asyncio库asyncdefmain():task1=asyncio.create_task(coroutine_one())task2=asyncio.create_task(coroutine_two())awaittask1awaittask2loop=asyncio.get_event_loop() loop.run_until_complete(main()) 要想运行创建的协程,可以通过asyncio库的run()和run_until_complete()方法实现。6.3.2协程爬虫实现技术asyncio.run(main()) 方式一方式二

aiohttp库aiohttp库是一个为Python提供的异步HTTP客户端/服务端编程的第三方库,在使用之前需要先进行安装。6.3.2协程爬虫实现技术pipinstallaiohttp

aiohttp库aiohttp库中提供了一个status属性,status属性用于获取请求的状态码,另外aiohttp库中还提供了很多方法。6.3.2协程爬虫实现技术方法说明ClientSession()用于创建客户端会话text()以字符串形式显示服务器内容json()以JSON形式响应服务器内容read()返回二进制文本post()发送POST请求get()发送GET请求

aiohttp库使用aiohttp库的get()方法请求百度首页,具体代码如下所示。6.3.2协程爬虫实现技术importasyncio,aiohttpasyncdefmain():#使用with语句的上下文管理器,保证处理session之后正确关闭

asyncwithaiohttp.ClientSession()assession:#使用get()方法发送GET请求

asyncwithsession.get('/')asresp:print(resp.status) #输出响应状态码asyncio.run(main())

aiofiles库aiofiles库提供文件异步操作,并非Python的标准库,所以使用之前需要先进行安装。6.3.2协程爬虫实现技术pipinstallaiofiles

aiofiles库aiofiles库中提供了许多与处理Python文件相似的方法,常用方法如下所示。6.3.2协程爬虫实现技术方法说明open()使用协程打开一个文件close()使用协程关闭文件read()使用协程读取文件,可设置读取的字节数realall()使用协程读取文件所有内容write()使用协程写入文件数据,可设置写入的字符长度writelines()使用协程写入文件数据,每次写入一行数据

aiofiles库使用aiofiles库向文件写入并读取数据,具体如下。6.3.2协程爬虫实现技术importasyncio,aiofilesasyncdefwirte_demo():asyncwithaiofiles.open("text.txt","w",encoding="utf-8")asfp:awaitfp.write("helloworld")print("数据写入成功")asyncdefread_demo():asyncwithaiofiles.open("text.txt","r",encoding="utf-8")asfp:content=awaitfp.read()print(content)多学一招事件循环是每个asyncio

应用的核心。事件循环会运行异步任务和回调,执行网络IO操作,以及运行子程序。await语句后需要跟随可等待对象,“可等待”可理解为跳转到等待对象,并将当前任务挂起,当等待对象的任务处理完成,再跳回当前任务继续执行。asyncio库中的可等待对象包括协程对象、协程任务和Future对象。可等待对象和事件循环掌握协程爬虫的实现技术,能够使用协程技术抓取黑马程序员论坛网站数据学习目标6.3.3协程爬虫基本示例以黑马程序员论坛网站为例,带领大家一起使用aiohttp、asyncio和aiofiles模块实现协程爬虫,并让协程爬虫采集Python技术交流版块中所有帖子的文章标题、文章作者、文章链接以及发布时间。6.3.3协程爬虫基本示例案例需求案例步骤6.3.3协程爬虫基本示例导入相关模块,定义协程函数定义请求网址并提取数据创建事件循环,启动协程函数123执行代码当程序运行后,可以看到在代码文件同级目录下添加了一个新的文件coroutine-heima.json,该文件存储了黑马程序员论坛中1~70页的文章标题、文章作者、文章链接和发布时间。6.3.3协程爬虫基本示例[单击查看源码]熟悉协程爬虫性能分析,能够计算出协程爬虫耗时时间学习目标6.3.4协程爬虫性能分析if__name__=='__main__':s_time=time.time()loop=asyncio.get_event_loop()#创建事件循环

loop.run_until_complete(main())e_time=time.time()print(f'总用时:{e_time-s_time}秒')为了对协程爬虫的性能进行分析,在6.3.3小节的示例的基础上,增加网络爬虫耗时计算的代码,比较单线程爬虫和协程爬虫在采集相同数据时总共耗费的时长。运行代码,结果如下。总用时:3.2851879596710205秒6.3.4协程爬虫性能分析通过比较单线程爬虫和协程爬虫耗费的时长可知,在相同的条件下,协程爬虫的性能优于单线程爬虫的性能。6.3.4协程爬虫性能分析[单击查看源码]实践项目:使用多线程采集黑马头条的评论列表6.4掌握黑马头条数据的抓取,能够使用多线程采集黑马头条的评论列表学习目标6.4使用多线程采集黑马头条的评论列表黑马头条是一款新闻资讯类项目,由用户端、自媒体端、管理后台端组成完整的业务闭环,通过大数据平台分析用户喜好,为用户精准推送资讯新闻。本节将使用多线程的知识开发一个多线程爬虫项目,采集黑马头条自媒体端指定页面范围的评论列表。6.4使用多线程采集黑马头条的评论列表

项目需求访问黑马头条自媒体端登录页面,使用默认的账号密码登录后,在左侧的菜单栏中选择“内容管理”→“评论列表”进入评论列表页面。

项目目标6.4使用多线程采集黑马头条的评论列表首先判断待提取的

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论