Python爬虫框架scrapy.Request()函数中meta参数的作用和使用方法

Python 全栈工程师核心面试 300 问深入解析(2020 版)----全文预览
Python 全栈工程师核心面试 300 问深入解析(2020 版)----欢迎订阅

初学scrapy可能会有点蒙圈,今天和大家分享下scrapy中Request方法中meta参数的用法 :

  1. 我们要知道meta参数对应的值必须是一个字典
  2. 它的主要作用是用来传递数据的
  3. meta是通过Request产生时传进去,
  4. 通过Response对象中取出来

先看一个简单的例子
在这里插入图片描述
然后查看两个爬虫实例,进一步理解meta参数的使用:

实例1

第一层爬取已经获得了一个Item对象,Item对象是一个字典,因此我们将Item对象通过meta参数,传递给第二层爬虫,第二层爬虫爬取的对象也继续添加封装到Item对象中,最终返回全部爬取的Item对象。meta就起了一个传递Item对象的作用

# coding: utf-8
import scrapy
from scrapy import Selector
from cnblogSpider.items import CnblogspiderItem

class CnblogsSpider(scrapy.Spider):
    # 爬虫的名称,唯一的,最好不要文件、文件夹名称重复,以免混淆
    name = 'cnblogs'
    # 允许的域名
    allowed_domains = ['cnblogs.com']
    # 入口URL列表,爬虫启动的接口
    start_urls = [
        'https://www.cnblogs.com/qiyeboy/default.html?page=1'
    ]

    # 首先定义parse方法,属于第一层爬取,
    # 然后定义一格parse_body方法,属于第二层爬取(需要使用第一层爬取的url)

    # parse方法,有一个response参数,该参数就是请求初始URL得到的内容
    # 通过该response开始爬虫后面的各个工作
    def parse(self, response):
        # 实现网页的解析
        # 首先抽取所有的文章,response中选择所有class='day'对应的节点元素
        # 分析原文可以发现,每一篇文章都是放在,<div class="day"> </div>标签里面
        # 选取的结果就是一个列表,就是多篇文章
        papers = response.xpath(".//*[@class='day']")
        # 从每篇文章中抽取数据
        for paper in papers:
            # 提取出一篇文章的地址,标题,时间,和内容(就是标题)
            # .从paper下面开始选,//不管在什么位置,*所有的,class='postTitle'属性下a标签下href属性的第一个值
            url = paper.xpath(".//*[@class='postTitle']/a/@href").extract()[0]
            # .从paper下面开始选,//不管在什么位置,*所有的,class='postTitle'属性下a标签下的第一个文字内容
            title = paper.xpath(".//*[@class='postTitle']/a/text()").extract()[0]
            time = paper.xpath(".//*[@class='dayTitle']/a/text()").extract()[0]
            # 提取文章的摘要
            content = paper.xpath(".//*[@class='c_b_p_desc']/text()").extract()[0]

            # 将提取到的数据封装成一个Item对象,封装之后类似一个字典,url为键,提取到的url地址就是值
            item = CnblogspiderItem(url=url, title=title, time=time, content=content)

            # 上面已经提取到了具体的一篇文章的地址,然后通过改地址,创建一个新的请求
            # 通过Request类请求,传入上面解析到的文章的URL,传入一个回调方法进行网页的解析
            # Request中有个meta参数,用来传递信息,传递信息的格式必须是一个字典类型,
            # 通过Request传进去,通过Request的请求结果response取出来,取出方法与字典一样
            request = scrapy.Request(url=url, meta={'item': item}, callback=self.parse_body)

            # 将parse打造成一个生成器,生成item,经过循环之后会生成很多item字典对象
            yield request # 函数生成器,相当于return返回request的值,request执行了parse_body方法,得到的就是一个item

        next_page = Selector(response).re(u'<a href="(\S*)">下一页</a>')
        if next_page:
            # url为请求的对象,callback为回调方法,指定由谁来解析请求的响应
            yield scrapy.Request(url=next_page[0], callback=self.parse)

    def parse_body(self, response):
        # 取出前面已经封装好的Item对象,里面已经包含了URL、标题、时间和摘要
        # 这里爬取图片的URL后,继续封装到Item里面去
        item = response.meta['item']
        # .意思选择匹配的当前节点,//选择文档中所有匹配当前节点的节点,不考虑他们的位置,
        # *匹文档中所有的元素,[@class='postBody'],匹配属性为class值为postBody的元素
        # 整个表达式含义,从response元素开始匹配文档中所有属性class='postBody'的元素,实际就是匹配的文章的正文内容
        body = response.xpath(".//*[@class='postBody']")
        # 找出了文章正文,然后匹配里面所有的图片链接
        # 下面表达式含义,从body元素节点开始匹配,找出所有的img元素下所有的src图片链接属性的值
        # extract()提取所有的内容,extract_first()和extract()[0]用来提取第一个内容,有时候一个标签下面有很多文字内容
        item['cimage_urls'] = body.xpath(".//img//@src").extract()
        yield item # 函数生成器,相当于返回item对象

实例2

#在items模块中有下面三个参数:
import scrapy
class TextItem(spider.Item):
    title = scrapy.Field()
    price = scrapy.Field()
    image = scrapy.Field()
#在spider爬虫中:
class TaobaoSpider(scrapy.Spider):
    name = ['taobao']
    allowed_domains = ['www.taobao.com']
    def parse1(self,response):
        '''
        需要知道的是item是一个字典
        '''
        item = TextItem()
        for product in response.css('......').extract():
            item['title'] = product.css('......').extract_first()
            item['price'] = product.css('......').extract_first()
            url = product.css('......').extract_first()
            yield = scrapy.Request(url=url, meta={'item':item} callback=self.parse2)
            '''
            比如我们要爬取淘宝上的商品,我们在第一层爬取时候获得了标题(title)和价格(price),
            但是还想获得商品的图片,就是那些点进去的大图片,假设点进去的链接是上述代码的url,
            利用scrpy.Request请求url后生成一个Request对象,通过meta参数,把item这个字典赋值给meta字典的'item'键,
            即meta={'item':item},这个meta参数会被放在Request对象里一起发送给parse2()函数。

            '''
    def parse2(self,response):
        item = response.meta['item']
        for product in response.css('......').extract():
            item[imgae] = product.scc('......').extract_first()
        return item
        '''
        这个response已含有上述meta字典,此句将这个字典赋值给item,完成信息传递。
        这个item已经和parse中的item一样了
        之后我们就可以做图片url提取的工作了,
        数据提取完成后return item ,这样就完成了数据抓取的任务了。

        '''

参考博文连接:
https://blog.csdn.net/wumxiaozhu/article/details/81368689
https://www.jianshu.com/p/666edd813d55

  • 24
    点赞
  • 60
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值