Scrapy需要抓取网站上的所有下一个链接,然后转到下一页

时间:2015-01-23 03:18:19

标签: python web-scraping scrapy web-crawler scrapy-spider

我需要我的scrapy继续下一页请给我正确的规则代码,怎么写?

from scrapy.contrib.spiders import CrawlSpider, Rule
from scrapy.selector import Selector
from scrapy.contrib.linkextractors.sgml import SgmlLinkExtractor

from delh.items import DelhItem

class criticspider(CrawlSpider):
    name ="delh"
    allowed_domains =["consumercomplaints.in"]
    #start_urls =["http://www.consumercomplaints.in/?search=delhivery&page=2","http://www.consumercomplaints.in/?search=delhivery&page=3","http://www.consumercomplaints.in/?search=delhivery&page=4","http://www.consumercomplaints.in/?search=delhivery&page=5","http://www.consumercomplaints.in/?search=delhivery&page=6","http://www.consumercomplaints.in/?search=delhivery&page=7","http://www.consumercomplaints.in/?search=delhivery&page=8","http://www.consumercomplaints.in/?search=delhivery&page=9","http://www.consumercomplaints.in/?search=delhivery&page=10","http://www.consumercomplaints.in/?search=delhivery&page=11"]
    start_urls=["http://www.consumercomplaints.in/?search=delhivery"]
    rules = (Rule(SgmlLinkExtractor(restrict_xpaths=('//div[@class="pagelinks"]/a/@href',)),           
              callback="parse_gen", follow= True),
    )
    def parse_gen(self,response):
        hxs = Selector(response)
        sites = hxs.select('//table[@width="100%"]')
        items = []

        for site in sites:
            item = DelhItem()
            item['title'] = site.select('.//td[@class="complaint"]/a/span/text()').extract()
            item['content'] = site.select('.//td[@class="compl-text"]/div/text()').extract()
            items.append(item)
        return items
spider=criticspider()

1 个答案:

答案 0 :(得分:1)

根据我的理解,你试图刮掉两种不同的页面,因此你应该使用两种不同的规则:

  • 分页列表页面,包含指向 n 项目页面和后续列表页面的链接
  • 项目页面,从中抓取您的物品

您的规则应该类似于:

rules = (
    Rule(LinkExtractor(restrict_xpaths='{{ item selector }}'), callback='parse_gen'),
    Rule(LinkExtractor(restrict_xpaths='//div[@class="pagelinks"]/a[contains(text(), "Next")]/@href')),
)

解释:

  • 第一条规则匹配项链接,并使用您的项解析方法(parse_gen)作为回调。生成的回复不会再次通过这些规则。
  • 第二条规则与“pagelinks”匹配,并且未指定回调,结果回复然后由这些规则处理。

注意:

  • SgmlLinkExtractor已过时,您应使用LxmlLinkExtractor(或其别名LinkExtractor)代替(source
  • 您发送请求的顺序很重要,在这种情况下(抓取未知的,可能很大的页面/项目数量),您应该设法减少任何给定的处理页数时间。为此,我以两种方式修改了您的代码:
    • 从当前列表页面中删除请求下一个项目的项目,这就是项目规则在“pagelinks”规则之前的原因。
    • 避免多次抓取网页,这就是我将[contains(text(), "Next")]选择器添加到“pagelinks”规则的原因。这样,每个“列表页面”只能被请求一次