又是采集绿色下载站的最新软件,又是采用另一种方式(前两种是采用正则和xpath),呵呵

感觉有点像孔乙已的茴字有几种写法了

这回用CrawlSpider,Rule来配合采集

这次不用生成许多start_urls列表项了,可以按规则来自动读取,贴核心代码

# -*- coding: utf-8 -*-from scrapy.contrib.spiders import CrawlSpider,Rulefrom scrapy.selector import Selectorfrom scrapy.http import Requestfrom scrapy.contrib.linkextractors import LinkExtractorclass MySpider(CrawlSpider):    name = "downg"    allowed_domains = ["downg.com"]    start_urls = [        'http://www.downg.com/new/0_1.html'    ]    rules = [        Rule(LinkExtractor(allow=('/new/0_\d\.html'),                              restrict_xpaths=('//div[@class="pages"]')),             callback='parse_pages',             follow=True)    ]    def parse_pages(self, response):        sel=Selector(response)        urlsReqs=[]        urls_list=sel.xpath('//span[@class="app-name"]/a/@href').extract()        print len(urls_list),urls_list        for url in urls_list:            req=Request(url,self.getDetail)            urlsReqs.append(req)        return urlsReqs    def getDetail(self,response):        print response.url

关键点解析:

LinkExtractor的allow定位列表页所匹配的正则

LinkExtractor的restrict_xpaths是定位列表页所在的xpath路径,当然,本案例中其实也可以不写
LinkExtractor的callback指定回调函数,注意,这里函数名不能用parse这个私有函数,不然跑起来会有问题
(来源,scrapy官方文档:
当编写爬虫规则时,请避免使用 parse 作为回调函数。 由于 CrawlSpider 使用 parse 方法来实现其逻辑,如果 您覆盖了 parse 方法,crawl spider 将会运行失败。
)
LinkExtractor的follow 是一个布尔(boolean)值,指定了根据该规则从response提取的链接是否需要跟进。 如果 callback 为None, follow 默认设置为 True ,否则默认为 False。本案例中用哪个值没有影响。
参考文章

update:

进一步优化版

# -*- coding: utf-8 -*-from scrapy.contrib.spiders import CrawlSpider,Rulefrom scrapy.selector import Selectorfrom scrapy.http import Requestfrom scrapy.contrib.linkextractors import LinkExtractorclass MySpider(CrawlSpider):    name = "downg"    allowed_domains = ["downg.com"]    start_urls = [        'http://www.downg.com/new/0_1.html'    ]    rules = [        Rule(LinkExtractor(allow=(r'new/0_\d\.html',)),follow=True),        Rule(LinkExtractor(restrict_xpaths=('//span[@class="app-name"]')),callback='getDetail',follow=False)    ]    def getDetail(self,response):        print 'result '+response.url