python yield 惰性计算,用于scrapy中(美食杰爬虫为例)

先说一下什么是python的惰性计算
惰性计算(Lazy evaluation)是指仅仅在真正需要执行的时候才计算表达式的值。充分利用其特性可以带来很多便利。yield的功能类似于return,但是不同之处在于它返回的是生成器。
惰性计算的好处:
1.避免不必要的计算,带来性能的提升。
对于Python中的条件表达式 if x and y,在x为false的情况下y表达式的值将不再计算。而对于if x or y,当x的值为true的时候将直接返回,不再计算y的值。因此编程中可以利用该特性,在 and逻辑中,将小概率发生的条件放在前面或者在or逻辑中,将大概率发生的时间放在前面,有助于性能的提升。
2.节省空间,使得无线循环的数据结构成为可能。
Python中最经典的使用延迟计算的例子就是生成式表达器了,它尽在每次需要计算的时候才通过yield产生所需要的元素。
以下介绍用法


为什么说yield类似于return而与return大不相同呢,用我写的代码看一下yield在scrapy中的用法。
# 这是一个spider类
class XiaoChiSpider(scrapy.Spider):
    name = 'xiaochi_spider'
    start_urls = ['https://www.meishij.net/china-food/xiaochi/']
    # 小吃的种类是很多种的,我在默认的parse解析方法中得到所有种类的地址,以此循环
    # callback到prasecontent中,分别对具体的小吃种类进行爬取
    def parse(self, response):
        xiaochi_list = response.xpath(
            "//div[@class='other_c listnav_con clearfix']//dl//dd//a//@href").extract()
        # 种类循环
        for xiaochi_url in xiaochi_list:
            # 这里体现了yield的用法
            # 可简单的把yield的作用理解为“抛出”,我把信息抛出,此时停止计算,等待prasecontent运算完成,继续执行yield的下一条代码,即遍历下一小吃种类
            yield scrapy.Request(xiaochi_url, callback=self.prasecontent)


    def prasecontent(self, response):
        # 获取下一页的url
        next_link = response.xpath("//div[@class='listtyle1_page']//a[@class='next']//@href").extract()
        split_name = re.split('/', next_link[0])
        cai_type = split_name[-2]+split_name[-3]

        xiaochi_juti = response.xpath(
            "//div[@class='main']//div[@class='listtyle1_list clearfix']//div[@class='listtyle1']//a")

        for i_item in xiaochi_juti:
            meishi_item = LiangCaiItem()

            meishi_item['cai_name'] = i_item.xpath(".//div[@class='c1']//strong//text()").extract_first()
            meishi_item['suoshu_type'] = i_item.xpath(
                "//div[@class='other_c listnav_con clearfix']//dl//dd[@class='current']//text()").extract()[0]

            try:
                redu = i_item.xpath(".//div[@class='c1']//span[1]//text()").extract_first().split('  ')
                meishi_item['cai_ReDu'] = redu[1]
            except:
                meishi_item['cai_ReDu'] = 'null'

            try:

                fenli = i_item.xpath(".//div[@class='c2']//li[@class='li2']//text()").extract_first().split(' / ')

                meishi_item['cai_KouWei'] = fenli[1]
                meishi_item['cai_ZuoFa'] = fenli[0]
            except:
                meishi_item['cai_KouWei'] = 'null'
                meishi_item['cai_ZuoFa'] = 'null'

            meishi_item['cai_HaoChu'] = i_item.xpath(".//strong[@class='gx']//text()").extract_first()
            meishi_item['cai_picture_path'] = i_item.xpath(".//img//@src").extract_first()

            meishi_item['cai_ZhiZuoRen'] = i_item.xpath(".//div[@class='c1']//em//text()").extract_first()

            meishi_item['cai_BuZhou'] = i_item.xpath(".//@href").extract_first()

            # 文件下载 保存的  调用
            murl = meishi_item['cai_BuZhou']
            html_file = DownloadMethod().download(murl)
            # 创建相应文件

            file_path = "C:/Users/ASUS/Desktop/Meishijie/"+cai_type+"/"
            if not os.path.exists(file_path):
                os.makedirs(file_path)

            DownloadMethod().save(file_path, re.split('/', murl)[-1], html_file)
            print("文件保存在:"+ file_path + re.split('/', murl)[-1])
            print("下载完成-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX")
            meishi_item['file_save_path'] = file_path + re.split('/', murl)[-1]

            yield meishi_item

        if next_link:
            next_link = next_link[0]
            yield scrapy.Request(next_link + "", callback=self.prasecontent)  # prase后不加括号

如果yield改为return,那扔出一次信息之后,这段代码即停止执行且不再运行。
以上代码中还体现了,文件的下载与保存到指定路径没有指定的路径时则新建)、scrapy爬虫的翻页
关于scrapy框架的知识欢迎提问探讨。

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值