前面说的是从一页爬取其中具体页面的方法,这算纵向爬取。现在来说说,横向爬取,就是一次爬取同一级别的多个页面,比如索引页从第一页到第5页,然后再纵向爬取每一索引页面中的具体页面。下图中1就是索引,2就是具体页面。假设抓取的信息全在具体页面之中。这就用crawlspider就很方便了。
页面分析crawlspider继承了spider类。
特别重要的是Rule,Rule用于过滤哪些网址要继续跟踪。基本语法是
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就好。
网友评论