作者:知乎用戶
鏈接:https://www.zhihu.com/question/54773510/answer/146971644
鏈接: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')}