1. 程式人生 > >Scrapy抓取在不同級別Request之間傳遞引數

Scrapy抓取在不同級別Request之間傳遞引數

先來看一下需求,以抓取簡書使用者資訊為例:

  • 使用者主頁左側顯示的資訊:(使用者主要資訊)
    • 使用者暱稱(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