scrapy-2.3CrawlSpider多页爬多页

前面说的是从一页爬取其中具体页面的方法,这算纵向爬取。现在来说说,横向爬取,就是一次爬取同一级别的多个页面,比如索引页从第一页到第5页,然后再纵向爬取每一索引页面中的具体页面。下图中1就是索引,2就是具体页面。假设抓取的信息全在具体页面之中。这就用crawlspider就很方便了。

scrapy-2.3CrawlSpider多页爬多页_第1张图片
页面分析

crawlspider继承了spider类。
特别重要的是Rule,Rule用于过滤哪些网址要继续跟踪。基本语法是


scrapy-2.3CrawlSpider多页爬多页_第2张图片
Rule基本语法

基本逻辑是在默认的情况下,先向start_urls发起request,scrapy会对其response自动抽取所有的href,url网址,根据Rule里的LinkExtractor匹配规则进行匹配,callback代表用哪个函数对找到网址进行分析。

有callback函数的Rule则默认不继续跟进,比如匹配的是具体页面地址,页面已是最深一层,则不需跟进,直接抽取放进item即可。没有callback的,则默认跟进,一般就是在下一页继续按Rule进行匹配。
这是默认情况,要是在有callback函数的情况下,又想继续跟进则follow=True即可,但是在函数里一般都会有yield scrapy.Request()来跟进。

LinkExtractor分两种,一种使用allow来控制网址,就是匹配的网址有共性,一般都是同级别,像....p1/p2,第1页第2页之类的,接受正则表达,比较简单的想把所有的链接都爬下来就把网址通用部分写出来即可,比如LinkExtractor(allow=('http://www.shicimingju.com/chaxun/zuozhe/13046_'))
另一种是用restrict_xpaths来控制,这种情况比较适合网址没什么共性,但是网址所在位置有共性,都放在html相似的位置上。比如
Rule(LinkExtractor(restrict_xpaths='//h3/a')
因为一直都用pyquery在解析网页,对xpath开始还有点懵,
restrict_xpaths

一个特别需要注意的点是,crawlspider不能使用parse这个名字来命名抽取函数。在文档里这样说。

这是文档中文翻译-版本有点低

from pyquery import PyQuery as pq
import scrapy
from zdm.items import ZdmItem,DoubanItem
from scrapy.spiders import CrawlSpider,Rule
from scrapy.linkextractors import LinkExtractor

class smzdmCrawler(CrawlSpider):
    name = 'shici'
    allow_domains =['shicimingju.com']
    start_urls =['http://www.shicimingju.com/chaxun/zuozhe/13046.html']
    rules =[
        Rule(LinkExtractor(allow=('http://www.shicimingju.com/chaxun/zuozhe/13046_'))),
        Rule(LinkExtractor(restrict_xpaths='//h3/a'),callback = 'parse_list')

    ]
    def parse_list(self, response):
        res = pq(response.body)
        smzdmitem = ZdmItem()
        smzdmitem['name'] =res('.shici-title').text()
        smzdmitem['price'] = res('.shici-info').text()
        yield smzdmitem

运行scrapy crawl shici -o shici.csv就好。

你可能感兴趣的:(scrapy-2.3CrawlSpider多页爬多页)