Python利用yield form实现异步协程爬虫
作者:红后
这篇文章主要为大家详细介绍了Python如何利用yield form实现异步协程爬虫。其实这是很古老的用法了,现在大多用的aiohttp库实现,这篇记录仅仅用做个人的协程底层实现的学习,希望对大家有所帮助
很古老的用法了,现在大多用的aiohttp库实现,这篇记录仅仅用做个人的协程底层实现的学习。
争取用看得懂的字来描述问题。
1.什么是yield
如果还没有怎么用过的话,直接把yield看做成一种特殊的return(PS:本质 generator(生成器))
return是返回一个值然后就终断函数了,而yield返回的是一个生成器(PS:不知道的直接看作特殊列表,看下面的代码案例)
# -*- coding: utf-8 -*- # @Time : 2022/11/10 16:17 # @Author : 红后 # @Email : not_enabled@163.com # @blog : https://www.cnblogs.com/Red-Sun # @File : 实例1.py # @Software: PyCharm def main(): ''' 遍历0到4,这五个数,并分别打印 ''' for num in range(5): yield num if __name__ == '__main__': for num in main(): print(num) print('-'*50) for num in [0, 1, 2, 3, 4]: print(num)
将它看作列表用for循环遍历,就能取出其中的值。
2.yield于列表的区别
它与原来列表的区别就在于,自带的列表是固定的,而把yield看作列表的话是动态的。
具体案例描述请看代码及备注(PS:个人自己描述的,有不对的地方望各位指点)
# -*- coding: utf-8 -*- # @Time : 2022/11/14 13:24 # @Author : 红后 # @Email : not_enabled@163.com # @blog : https://www.cnblogs.com/Red-Sun # @File : 实例2.py # @Software: PyCharm def main(): ''' 将yield看作一个动态列表,从yield左往右为传出数据,从又往左为传入数据。 PS:有yield存在的那一行,需要从左往右传出数据跑一遍,数据出去以后又要从又往左带接收的数据跑一遍,一共一行跑两边(仅作者个人记忆方法) ''' num1 = yield num2 = yield print(num1, num2) yield num1 + num2 if __name__ == '__main__': a = main() # 第一个next对应第一个yield的右边为空即None,所以动态列表中加入一个参数为None,返回值为列表的-1位是None print(next(a)) # [None] # 第二个通过send方法传入一个数1,即在上一次停止的地方从右往左传入参数,所以给num1赋值为1.然后继续找下一个yield,其右边的值依旧为None,加入动态列表,此时返回值-1位依旧是None print(a.send(1)) # [None, None] # 第三通过send方法传入一个数2,即在上一次停止的地方从右往左传入参数,所以给num2赋值为2.然后继续找下一个yield,其右边的值为num1 + num2,此时num1为1,num2为2,计算得返回值-1位为3 print(a.send(2)) # [None, None, num1 + num2]
3.yield from 实现协程
yield from 后面需要加可迭代对象
当它后面加上生成器(上述所说的yield这种)便可以实现生成的嵌套
- 老板(主程序):调用委派生成器
- 包工头(委派生成器):包含yield from表达式的生成器
- 打工仔(子生成器):生成器函数
其中委派生成器的作用:在主程序与子生成器之间建立一个双向通道。
所谓双向通道是指,主程序可以将参数通过send传递给子生成器,子生成器的yield的值也可以直接返回给主函数。(PS:委派生成器只有创建通道的作用,没有拦截数据这种功能)
也许有人会想直接用主程序调用子生成器不就行了,而对这的解释是,使用yield from作为中间过渡是为了让它帮我们进行异常处理(PS:类似写程序为了正常运行加上try一个道理)
# -*- coding: utf-8 -*- # @Time : 2022/11/10 15:13 # @Author : 红后 # @Email : not_enabled@163.com # @blog : https://www.cnblogs.com/Red-Sun # @File : coroutines.py # @Software: PyCharm import requests def coroutines_spider(): ''' 子生成器(PS: 打工仔,真正干活的) ''' response = None # 首次激活返回None,后期网页响应覆盖 while True: url = yield response response = requests.get(url) def appoint(): ''' 委派生成器,委托子生成器完成具体任务 (PS: 类似包工头负责劳务派遣) ''' while True: yield from coroutines_spider() # 建立子生成器和主函数的双通道 def main(url_list: list): ''' 主函数(PS: 相当于老板,张贴招人启示) ''' ul = appoint() # 创建委派生成器 next(ul) # 激活它 for url in url_list: response = ul.send(url) # 将url作为参数传递进入子生成器中,返回子生成器yield出来的response print(response.url, response.status_code) # 打印出response中的链接和状态码 if __name__ == '__main__': url_list = ['https://www.baidu.com/', 'https://www.4399.com/', 'https://cn.bing.com/', ] main(url_list=url_list)
到此这篇关于Python利用yield form实现异步协程爬虫的文章就介绍到这了,更多相关Python yield form异步协程爬虫内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
您可能感兴趣的文章:
- Python7个爬虫小案例详解(附源码)中篇
- Python7个爬虫小案例详解(附源码)上篇
- Python爬虫程序中使用生产者与消费者模式时进程过早退出的问题
- Python爬虫库urllib的使用教程详解
- python爬虫之requests库使用代理方式
- python 基于aiohttp的异步爬虫实战详解
- Python爬虫框架NewSpaper使用详解
- 通过python爬虫mechanize库爬取本机ip地址的方法
- Python爬虫学习之requests的使用教程
- python爬虫beautiful soup的使用方式
- Python爬虫之超级鹰验证码应用
- Python爬虫Requests库的使用详情
- python爬虫模拟登录之图片验证码实现详解
- Python爬虫eval实现看漫画漫画柜mhgui实战分析
- python爬虫实战项目之爬取pixiv图片
- 使用python爬虫实现子域名探测问题
- python爬虫之代理ip正确使用方法实例
- Python7个爬虫小案例详解(附源码)下篇