• scrapy的request的meta参数是什么意思?


    作者:乌尔班
    链接:https://www.zhihu.com/question/54773510/answer/146971644
    来源:知乎
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

    Request中meta参数的作用是传递信息给下一个函数,使用过程可以理解成:

    把需要传递的信息赋值给这个叫meta的变量,
    但meta只接受字典类型的赋值,因此
    要把待传递的信息改成“字典”的形式,即:
    meta={'key1':value1,'key2':value2}
    
    如果想在下一个函数中取出value1,
    只需得到上一个函数的meta['key1']即可,
    因为meta是随着Request产生时传递的,
    下一个函数得到的Response对象中就会有meta,
    即response.meta,
    取value1则是value1=response.meta['key1']
    

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

    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'键(记住meta本身也是一个字典)。
               Scrapy.Request请求url后生成一个"Request对象",这个meta字典(含有键值'key','key'的值也是一个字典,即item)
               会被“放”在"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')}

     
  • 相关阅读:
    如果前面的IO操作出问题了,按照我们代码的意思,不就try catch 了吗,这样的话线程就没关闭了,就会造成线程泄露。 那怎么解决这个问题呢,其实也简单,把关闭线程的方法写到finally里就可以了。
    Dataeye计算任务架构
    Mercury:唯品会全链路应用监控系统解决方案详解(含PPT)
    app 爬虫
    唯品会HDFS性能挑战和优化实践
    构建Hadoop监控共同体
    消除单点故障 flume
    时间戳 Flume's Memory Consumption
    telnet nmap netstap
    hdfs ha
  • 原文地址:https://www.cnblogs.com/lmx123/p/9407107.html
Copyright © 2020-2023  润新知