2013-01-19 37 views
3
from scrapy.spider import BaseSpider 
from scrapy.selector import HtmlXPathSelector 
from manga.items import MangaItem 

class MangaHere(BaseSpider): 
    name = "mangah" 
    allowed_domains = ["mangahere.com"] 
    start_urls = ["http://www.mangahere.com/seinen/"] 

    def parse(self,response): 
     hxs = HtmlXPathSelector(response) 
     sites = hxs.select('//ul/li/div') 
     items = [] 
     for site in sites: 
      rating = site.select("p/span/text()").extract() 
      if rating > 4.5: 
       item = MangaItem() 
       item["title"] = site.select("div/a/text()").extract() 
       item["desc"] = site.select("p[2]/text()").extract() 
       item["link"] = site.select("div/a/@href").extract() 
       item["rate"] = site.select("p/span/text()").extract() 
       items.append(item) 

     return items 

我的目標是抓取www.mangahere.com/seinen或該網站上的任何內容。我想瀏覽每一頁並收集大於4.5分的書籍。我最初是作爲一個基地蜘蛛,並試圖複製和閱讀scrapy教程,但它幾乎讓我感到頭疼。我在這裏問我該如何創建我的規則,以及如何做。我似乎也無法讓自己的條件起作用,代碼或者只返回第一個條目,無論條件如何都會停下來,或者不管條件如何都會抓取所有內容。我知道它可能很糟糕的代碼,但我仍然努力學習。隨意摸了代碼或提供其他建議我如何爲使用scrapy的爬行器創建規則

回答

6

嚴格地說,這不是回答這個問題,因爲我的代碼使用BaseSpider而不是CrawlSpider,但它確實滿足了OP的要求,所以...

注意事項:

  1. 由於所有分頁鏈接所不具備的(你得到的前九個,然後最後兩個),我使用一個有點hacktastic方法。使用parse回調函中的第一個響應,我搜索一個帶有「next」類的鏈接(只有一個,因此查看它對應的鏈接),然後查找其之前的兄弟節點。這使我能夠處理seinen類別(當前爲45)中的頁面總數。
  2. 接下來,我們爲parse_item回調處理的第一頁產生Request對象。
  3. 然後,鑑於我們確定總共有45個頁面,我們爲「./seinen/2.htm」生成一系列「./seinen/45.htm」的Request對象。
  4. 由於rating是一個列表,並且它的值是浮點數(我應該在條件爲4.5的基礎上認識到這一點),修復遇到的錯誤的方法是遍歷評級列表並將每個項目轉換爲成爲一個浮動。

無論如何,看看下面的代碼,看看它是否有意義。從理論上講,你應該能夠很容易地擴展這些代碼來分割多個類別,儘管這只是OP的一個練習。 :)

from scrapy.spider import BaseSpider 
from scrapy.contrib.linkextractors.sgml import SgmlLinkExtractor 
from scrapy.selector import HtmlXPathSelector 
from scrapy.http import Request 
from tutorial.items import MangaItem 
from urlparse import urlparse 

class MangaHere(BaseSpider): 
    name = "mangah2" 
    start_urls = ["http://www.mangahere.com/seinen/"] 
    allowed_domains = ["mangahere.com"] 

    def parse(self, response): 
     # get index depth ie the total number of pages for the category 
     hxs = HtmlXPathSelector(response) 
     next_link = hxs.select('//a[@class="next"]') 
     index_depth = int(next_link.select('preceding-sibling::a[1]/text()').extract()[0]) 

     # create a request for the first page 
     url = urlparse("http://www.mangahere.com/seinen/") 
     yield Request(url.geturl(), callback=self.parse_item) 

     # create a request for each subsequent page in the form "./seinen/x.htm" 
     for x in xrange(2, index_depth): 
      pageURL = "http://www.mangahere.com/seinen/%s.htm" % x 
      url = urlparse(pageURL) 
      yield Request(url.geturl(), callback=self.parse_item) 

    def parse_item(self,response): 
     hxs = HtmlXPathSelector(response) 
     sites = hxs.select('//ul/li/div') 
     items = [] 
     for site in sites: 
      rating = site.select("p/span/text()").extract() 
      for r in rating: 
       if float(r) > 4.5: 
        item = MangaItem() 
        item["title"] = site.select("div/a/text()").extract() 
        item["desc"] = site.select("p[2]/text()").extract() 
        item["link"] = site.select("div/a/@href").extract() 
        item["rate"] = site.select("p/span/text()").extract() 
        items.append(item) 
     return items 
+0

ahhh這是有道理的,我試過浮動(評級),但沒有工作出於某種原因,謝謝。我會重新測試代碼,並返回結果 – gallly

+0

它說我不能將評級變成一個整數,因爲它是一個列表,我如何使它不返回一個列表? – gallly

+0

非常感謝您的幫助! – gallly