[转]scrapy中的request.meta

作者:知乎用户
链接:https://www.zhihu.com/question/54773510/answer/146971644

meta属性是字典,字典格式即{‘key’:'value'},字典是一种可变容器模型,可存储任意类型对象。

request中meta参数的作用是传递信息给下一个函数,这些信息可以是任意类型的,比如值、字符串、列表、字典......方法是把要传递的信息赋值给meta字典的键,分析见如下语句(爬虫文件):


class example(scrapy.Spider):
    name='example'
    allowed_domains=['example.com']
    start_urls=['http://www.example.com']
    def parse(self,response):
           #从start_urls中分析出的一个网址赋值给url
           url=response.xpath('.......').extract()
           #ExamleClass是在items.py中定义的,下面会写出。item本身是一个字典
           item=ExampleClass()
           item['name']=response.xpath('.......').extract()
           item['htmlurl']=response.xpath('.......').extract()
           #通过meta参数,把item这个字典,赋值给meta(本身也是一个字典)
           #中的key键。Request在请求url后生成一个request对象,这个
           #(含有键值'key','key'的值是字典item)meta字典
           #里面的信息会被“放”在request对象里一起发送给parse2()函数 
           yield Request(url,meta={'key':item},callback='parse2')
     def parse2(self,response):
           item=response.meta['key']
           #这个response已含有上述meta字典,此句将这个字典赋值给item,完成信息传递。
           #这个item已经和parse中的item一样了
           item['text']=response.xpath('.......').extract()#item共三个键值,到这里全部添加完毕了
           yield item

items.py中语句如下:

class ExampleClass(scrapy.Item):
    name = scrapy.Field()
    htmlurl = scrapy.Field()
    text=scrapy.Field()

meta当然是可以传递cookie的(第一种):

下面start_requests中键‘cookiejar’是一个特殊的键,scrapy在meta中见到此键后,会自动将cookie传递到要callback的函数中。既然是键(key),就需要有值(value)与之对应,例子中给了数字1,也可以是其他值,比如任意一个字符串。

def start_requests(self):
    yield Request(url,meta={'cookiejar':1},callback=self.parse)

需要说明的是,meta给‘cookiejar’赋值除了可以表明要把cookie传递下去,还可以对cookie做标记。一个cookie表示一个会话(session),如果需要经多个会话对某网站进行爬取,可以对cookie做标记,1,2,3,4......这样scrapy就维持了多个会话。

def parse(self,response):
    key=response.meta['cookiejar']    #经过此操作后,key=1
    yield Request(url2,meta={'cookiejar'key},callback='parse2')
def parse2(self,response):
    pass

上面这段和下面这段是等效的:

def parse(self,response):
    yield Request(url2,meta={'cookiejar'response.meta['cookiejar']},callback='parse2')
    #这样cookiejar的标记符还是数字1
def parse2(self,response):
    pass

传递cookie的第二种写法:

如果不加标记,可以用下面的写法:

#先引入CookieJar()方法
from scrapy.http.cookies import CookieJar

写spider方法时:

def start_requests(self):
    yield Request(url,callback=self.parse)#此处写self.parse或‘parse’都可以
def parse(self,response):
    cj = response.meta.setdefault('cookie_jar', CookieJar())
    cj.extract_cookies(response, response.request)
    container = cj._cookies
    yield Request(url2,cookies=container,meta={'key':container},callback='parse2')
def parse2(self,response):
    pass

meta是浅复制,必要时需要深复制。

可以这样引入:

import copy
meta={'key':copy.deepcopy('value')}
posted @ 2017-06-18 17:02  道高一尺  阅读(3575)  评论(0编辑  收藏  举报