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 的书籍。我最初是一名 basespider,并尝试复制和阅读 scrapy 教程,但它几乎让我无法理解。我在这里问我要做什么来创建我的规则,以及如何。我似乎也无法让我的条件正常工作,代码要么只返回第一个项目并且不管条件如何都停止,或者抓住一切,再次不管条件。我知道它的代码可能很混乱,但我仍在努力学习。随意修改代码或提供其他建议

4

1 回答 1

6

严格来说,这并没有回答问题,因为我的代码使用 aBaseSpider而不是 a CrawlSpider,但它确实满足了 OP 的要求,所以......

注意事项:

  1. 由于所有的分页链接都不可用(你得到前九个,然后是最后两个),我采用了一种有点 hacktastic 的方法。使用parse回调中的第一个响应,我搜索具有“下一个”类的链接(只有一个,所以看看它对应于哪个链接),然后找到它的前一个兄弟。这让我掌握了 seinen 类别的总页数(目前为 45)。
  2. 接下来,我们为要由parse_item回调处理的第一页生成一个 Request 对象。
  3. 然后,假设我们已经确定总共有 45 个页面,我们为“./seinen/2.htm”生成一系列请求对象,一直到“./seinen/45.htm”。
  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
于 2013-01-20T00:59:56.730 回答