簡體   English   中英

如何爬取多級頁面到Scrapy中的一項?

[英]How to crawl multiple-level pages to one item in Scrapy?

我找到的 Scrapy 的所有例子都在講如何爬取單個頁面,或者如何爬取多級頁面,當每個最深的頁面都保存為一個獨立的Item時。 但是我的情況有點復雜。

例如,網站結構是:

A (List page of books)
--> B (Book summary page)
----> C (Book review pages)
----> D (Book download pages)

因此Item的定義如下所示:

class BookItem(scrapy.Item):
    name = scrapy.Field()
    type = scrapy.Field()
    introduction = scrapy.Field()
    resources = scrapy.Field() # To be a list of ResourceItem
    reviews = scrapy.Field() # To be a list of ReviewItem

# Download pages
class ResourceItem(scrapy.Item):
    title = scrapy.Field()
    createDate = scrapy.Field()
    author = scrapy.Field()
    link = scrapy.Field()


# Book reviews
class ReviewItem(scrapy.Item):
    title = scrapy.Field()
    createDate = scrapy.Field()
    author = scrapy.Field()
    content = scrapy.Field()

我怎樣才能完成BookItem的所有字段? 知道我可以編寫 4 種方法,例如parse_A()parse_B()parse_C()parse_D() ,而 Scrapy 通過在每個方法的末尾使用yield scrapy.Request()允許它們成為一個工作流。

但是我應該在最深層的方法中返回什么,即parse_C()parse_D()

  1. 如果我返回ResourceItemReviewItem ,它將被直接保存。
  2. 如果我從上層方法返回BookItem ,未完成的項目也將直接保存。
  3. 如果我在parse_C() parse_D()Request ,它也不會起作用,因為資源可能是空的(也就是說 B 頁面上可能根本沒有 C 的鏈接)。 所以parse_C()不會被調用,留下parse_D()未被調用,最后 D 字段未填充。

您可以使用meta參數傳遞一些數據(請參閱https://docs.scrapy.org/en/latest/topics/request-response.html )。

因此,您可以在多個請求/解析函數中填充您的項目。

顯示邏輯的快速示例:

def parse_summary(self, response):
  book_item = # scrape book item here
  reviews_url = # extract reviews url 
  resources_url = # extract resources url
  return scrapy.Request(reviews_url, callback=self.parse_reviews, meta={'item': book_item, 'resources_url': resources_url })

def parse_reviews(self, response):
  book_item = response.meta.get('item') # get item draft
  book_item.reviews = # extract reviews here
  resources_url = response.meta.get('resources_url')
  return scrapy.Request(resources_url, callback=self.parse_resources, meta={'item': book_item })

def parse_resources(self, response):
  book_item = response.meta.get('item') # get item draft
  book_item.ressources = # extract ressources here
  return book_item # once completed, return the item

希望你能明白(我對代碼執行不是很自信,只是寫下來沒有測試)。

我現在可以自己回答了。

只需yield None省略parse_C()parse_D()中的 return 語句即可解決問題。

一些解釋

Scrapy 不會僅僅因為其中一個回調什么都不返回就關閉蜘蛛,但要確保請求隊列中也沒有新的回調。

因此,由於parse_B()在完成產生子頁面 C & D 的所有請求之前不會返回NoneItem ,因此工作流不會中斷。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM