yield的使用和在scrapy框架中的使用
yield的基本使用
yield一般多用于生成器的创建,通过next()和send方法进行调用。
def demo01():print('start! 第1次循环')for i in range(10):c = yield iprint('c ---->',c,'\n')print('!!!!end!!!! 第%d次循环'%(i+1))if __name__ == '__main__':d = demo01()print('=========')print('第一次打印返回值:',next(d))print('=========')print('第二次打印返回值:',d.send(11))print('=========')print('第3次打印返回值:',next(d))
结果:
=========
!!!!start!!!! 第1次循环
第一次打印返回值: 0
=========
c ----> 11
!!!!end!!!! 第1次循环
第二次打印返回值: 1
=========
c ----> None
!!!!end!!!! 第2次循环
第3次打印返回值: 2
如果把yield看作是一个return,那么执行到yield的时候就是返回指定的数据,然后跳出函数。
- 此时 d 就是一个生成器,由于函数没有被执行过,执行第一个next时,函数正式被运行,做第一步的print输出,然后进入for循环,遇到yield后返回指定 i 值并跳出函数执行,此时 i =0,所以第一次打印的返回值为0
- 第二步使用了send()函数,此时从赋值的那一步开始执行(即通过yield跳出的那一步)并将传入的值赋值给了c,此时c = 11,然后继续向下执行,结束第一次循环,再次循环遇到yield时,返回的 i 值为1。
- 第三步再次使用了next方法,依旧从跳出的那一步开始向下执行,结束第2次循环,再次遇到yield时,返回 i 值,此时 i = 2。
- 但是,在结束第2次循环之前,在打印c的时候显示c = None。这是因为在第二步使用send函数跳出后,c并没有被赋值,在执行左边的yield时,就已经跳出了所以并没有执行复制的操作,所以这是默认赋值为None,所以在进行第三步时,c为None。
综上所述可以看出,两种调用方法,都是从上一步结束的地方继续执行,next()不会传入参数,而send可以向函数内传入参数,通过yield的位置传参。
def demo02():for i in range(10):c = yield iprint('c1 ---->',c)def demo03():for i in range(10):yield ic = i print('c2 ----->',c)d2 = demo02()
d3 = demo03()
next(d2)
next(d3)
d2.send(11)
d3.send(11)===结果===
c1 ----> 11
c2 -----> 0
demo03中虽然依旧使用了send传参,但是继续执行上一步终止处的程序后,新传入的参数并没有被赋值,因此传入的参数无效。
常见yield的异常
TypeError: can't send non-None value to a just-started generator
第一次调用生成器时,只能用send(None)或next()方法,不要直接send赋值,不然会报这个错误。
官方文档里详细解释了这个异常。是因为当生成器创建,从顶部开始执行函数时,并没有可以接收yield值的表达式,所以不可以使用带有非None参数的send(),必须提前调用一次send(None)或next()方法。
官方说明如下:
Because generator-iterators begin execution at the top of the
generator’s function body, there is no yield expression to receive a value when the generator has just been created. Therefore, calling send() with a non-None argument is prohibited when the generator iterator has just started, and a TypeError is raised if this occurs (presumably due to a logic error of some kind). Thus, before you can communicate with a coroutine you must first call next() or send(None) to advance its execution to the first yield
StopIteration
每一次调用next()方法后都会执行到yield位置结束,然后返回值,如果程序已经执行到最低端无法继续向下执行,此时仍然调用了方法,就会抛出这个异常。
在scrapy中关于yield的使用
在scrapy中,关于yield最常见的两个操作就是yield scrapy.Request
和yield scrapy.item
scrapy.Request
def parse(self,response):···yield scrapy.Request(url=url,callback=self.detail_parse)
向response中获取的新链接再次发起请求,请求完成后调用指定回调函数。
scrapy.item
def detail_parse(self,response):item = DemoItem()····yield item
通过yield将获取的item传输到管道文件进行下一步处理。
在scrapy中使用yield时遇到的注意事项
如果在scrapy中定义了一个非回调函数,那么在这个函数中无法进行yield scrapy.Request
和yield scrapy.item
的操作,此时yield在这里起到的是它本身的基础作用,不是scrapy赋予它的作用,而使用了yield的非回调函数也只是一个普通的生成器。
yield的使用和在scrapy框架中的使用相关推荐
- scrapy框架中实现登录人人网(一)(最新登录方式)
最近在弄scrapy框架的问题,感觉里面好玩的东西有很多,无意中在bilibili中看到关于在scrapy实现登录人人网的视频,人人网可能用户少,所以在现在的一些博客和教程里面看到最新的登录方法几乎没 ...
- 在scrapy框架中如何设置开放代理池达到反爬的目的
我们在随机爬取某个网站的时候,比如对网站发出成千上万次的请求,如果每次访问的ip都是一样的,就很容易被服务器识别出你是一个爬虫.因此在发送请求多了之后我们就要设置ip代理池来随机更换我们的ip地址,使 ...
- Scrapy框架中的crawlspider爬虫
1 crawlspider是什么 在spider中要寻找下一页的url地址或者内容的url地址,想想是否有简单的方法省略寻找url的过程? 思路: 从response中提取所有的满足规则的url地址 ...
- python pipeline框架_Python爬虫从入门到放弃(十六)之 Scrapy框架中Item Pipeline用法...
原博文 2017-07-17 16:39 − 当Item 在Spider中被收集之后,就会被传递到Item Pipeline中进行处理 每个item pipeline组件是实现了简单的方法的pytho ...
- Python爬虫从入门到放弃(十五)之 Scrapy框架中Spiders用法
Spider类定义了如何爬去某个网站,包括爬取的动作以及如何从网页内容中提取结构化的数据,总的来说spider就是定义爬取的动作以及分析某个网页 工作流程分析 以初始的URL初始化Request,并设 ...
- Scrapy框架中解决OSError=[Errno 2] No such file or directory: 'Xvfb': 'Xvfb'
当在scrapy框架的Middlewares.py中导入以下语句后报错 from pyvirtualdisplay import Display display = Display(visible=0 ...
- Scrapy框架中管道的使用
1. pipeline中常用的方法: 管道能够实现数据的清洗和保存,能够定义多个管道实现不同的功能,其中有个三个方法: process_item(self,item,spider):实现对item数据 ...
- python中scrapy的middleware是干嘛的_Python之爬虫(十九) Scrapy框架中Download Middleware用法...
这篇文章中写了常用的下载中间件的用法和例子. Downloader Middleware处理的过程主要在调度器发送requests请求的时候以及网页将response结果返回给spiders的时候,所 ...
- Scrapy框架的学习(11.scrapy框架中的下载中间件的使用(DownloaderMiddlewares))
1.Downloader Middlewares (下载中间键):引擎会先把Requets对象交给下载中间键再然后交给Downloader 2.使用方法: (1) 编写一个Downloader Mid ...
最新文章
- Apple首篇AI文章,SimGAN
- Week2 Teamework from Z.XML 软件分析与用户需求调查(四)Bing桌面及助手的现状与发展...
- 将C4C Service Request中的summary和其他附件同步到ERP的Billing Request去
- 如何在IE地址栏显示自己的小图标
- activiti-explorer 启动报错 Error creating bean with name 'demoDataConfiguration'
- 《机器学习实战》第二章学习笔记:K-近邻算法(代码详解)
- Cesium:在地球上加载Geoserver图层
- 数值分析实验四 最小二乘法曲线拟合
- 进qq空间显示服务器失败,QQ空间找不到服务器-进空间找不到服务器的解决办法...
- UE4数据库 Mysql
- 利用python爬取教务系统中成绩
- 【魔方攻略】镜面魔方教程(原创)
- 和异性合租是什么样的体验?
- 微信移动端数据库组件WCDB系列(二) — 数据库修复三板斧
- 2021年10个最美的边框效果,CSS实现,可以直接使用
- 华为交换机traffic策略设置
- 优维科技应用CMDB在招商基金的案例分享
- 26岁,2020 - 观周浩《书记》
- Deep Splitting and Merging for Table Structure Decomposition 中文翻译 (表格结构识别)
- 在容器中编译go项目出现cannot find packages的问题