天天看點

Scrapy抓取在不同級别Request之間傳遞參數

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

  • 使用者首頁左側顯示的資訊:(使用者主要資訊)
    • 使用者昵稱(nickname)
    • 關注數(subs)
    • 粉絲(fans)
    • 文章(articles)
    • 字數(words)
以上資料從使用者首頁可以擷取(/latest_articles),其他頁面(/timeline, /followers...)都有這些資料。
Scrapy抓取在不同級别Request之間傳遞參數

使用者首頁可以得到的資料

  • 我們還關注的資訊:(反映使用者活躍度的其他資料)
    • 使用者文章總閱讀量(read_nums)
    • 使用者獲得打賞數量(rewards)
    • 使用者獲得評論數量(comments)
    • 使用者發表的評論數量(pub_comments)
    • 使用者注冊時間(regtime)

以上資料在包含在兩個(類)頁面中:

1)閱讀量、打賞量、評論數量3個資料在latest_articles頁面上,需要彙總得到,每頁中每條(每篇文章)彙總,然後分頁彙總所有文章的這3個資料。

2)使用者發表的其他評論和注冊時間,在timeline頁面上,其中使用者發表的評論需要在timeline頁面上每頁彙總,注冊時間在timeline最後一頁。

Scrapy抓取在不同級别Request之間傳遞參數

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