先來看一下需求,以抓取簡書使用者資訊為例:
- 使用者首頁左側顯示的資訊:(使用者主要資訊)
- 使用者昵稱(nickname)
- 關注數(subs)
- 粉絲(fans)
- 文章(articles)
- 字數(words)
以上資料從使用者首頁可以擷取(/latest_articles),其他頁面(/timeline, /followers...)都有這些資料。
使用者首頁可以得到的資料
- 我們還關注的資訊:(反映使用者活躍度的其他資料)
- 使用者文章總閱讀量(read_nums)
- 使用者獲得打賞數量(rewards)
- 使用者獲得評論數量(comments)
- 使用者發表的評論數量(pub_comments)
- 使用者注冊時間(regtime)
以上資料在包含在兩個(類)頁面中:
1)閱讀量、打賞量、評論數量3個資料在latest_articles頁面上,需要彙總得到,每頁中每條(每篇文章)彙總,然後分頁彙總所有文章的這3個資料。
2)使用者發表的其他評論和注冊時間,在timeline頁面上,其中使用者發表的評論需要在timeline頁面上每頁彙總,注冊時間在timeline最後一頁。
timeline頁面上要抓取的資料
一個使用者完整的資訊要在多個Request中擷取,需要在請求之間傳遞參數。
直到該使用者所有頁面資料彙總完成,送出item。
Scrapy采用的是回調(callback)的方式,把請求處理交給下一次請求,在請求時用meta傳遞參數。
Request(url=item_details_url, meta={'item': item},callback=self.parse_details)
,可傳遞簡單類型參數或對象類型參數。
def parse(self, response):
# collect `item_urls`
for item_url in item_urls:
yield Request(url=item_url, callback=self.parse_item)
def parse_item(self, response):
item = MyItem()
# populate `item` fields 收集處理一部分資料
yield Request(url=item_details_url, meta={'item': item},
callback=self.parse_details)
def parse_details(self, response):
item = response.meta['item']
# populate more `item` fields 再收集處理另外的資料
return item
這樣完成一個使用者所有資料收集,注意以上示例代碼沒有包含分頁遞歸調用。
PS:
1) 傳遞多個參數:
yield Request(url, meta={'item': item, 'rdt': rdt, 'comments':cmt,'rewards':rewards,'total': total, 'curpage': cur}, callback=self.parse)
取出多個參數。如果不同url過來的加上判斷。(如針對分頁)
item = response.meta['item']
rdt = response.meta['rdt']
total = response.meta['total']
cur = int(response.meta['curpage'])
cmt = int(response.meta['comments'])
rewards= int(response.meta['rewards'])
原文連結:http://www.jianshu.com/p/de61ed0f961d