Scrapy笔记:CrawSpider中rules中的使用
scrapy.spiders.crawl.CrawlSpider类的使用
这个类比较适用于对网站爬取批量网页,相比于Spider类,CrawlSpider主要使用规则(rules)来提取链接
rules = (
Rule(LinkExtractor(allow=(r'https://movie.douban.com/subject/\d+/')), callback="parse_item1"),
Rule(LinkExtractor(allow=(r'https://movie.douban.com/subject/.+')), callback="parse_item2"),
)
如果接触过django,那么可以发现这个规则与django的路由系统十分相似,CrawlSpider的rules属性是直接从response对象的文本中提取url,然后自动创建新的请求。与Spider不同的是,CrawlSpider已经重写了parse函数,因此我们可以看到,scrapy的官网文档的例子中并没有重写parse。
这一切是scrapy自动实现的,具体过程是:
scrapy crawl spidername开始运行,程序自动使用start_urls构造Request并发送请求,然后调用parse函数对其进行解析,在这个解析过程中使用rules中的规则从html(或xml)文本中提取匹配的链接,通过这个链接再次生成Request,如此不断循环,直到返回的文本中再也没有匹配的链接,或调度器中的Request对象用尽,程序才停止。
rules中的规则如果callback没有指定,则使用默认的parse函数进行解析,如果指定了,那么使用自定义的解析函数。
如果起始的url解析方式有所不同,那么可以重写CrawlSpider中的另一个函数parse_start_url(self, response)用来解析第一个url返回的Response,但这不是必须的。
Rule对象的follow参数的作用是:指定了根据该规则从response提取的链接是否需要跟进。
参考: http://scrapy-chs.readthedocs.io/zh_CN/stable/topics/spiders.html#crawling-rules
1 #!/usr/bin/python 2 # -*- coding: utf-8 -*- 3 4 import scrapy 5 from tutorial01.items import MovieItem 6 from scrapy.spiders.crawl import Rule, CrawlSpider 7 from scrapy.linkextractors import LinkExtractor 8 9 10 class DoubanmoviesSpider(CrawlSpider): 11 name = "doubanmovies" 12 allowed_domains = ["douban.com"] 13 start_urls = ['https://movie.douban.com/tag/'] 14 # http_user='username' #http协议的基本认证功能 ;http_user和http_pass 15 # http_pass='password' 16 rules = ( #自动从response中根据正则表达式提取url,再根据这个url再次发起请求,并用callback解析返回的结果 17 Rule(LinkExtractor(allow=(r'https://movie.douban.com/subject/\d+/')), callback="parse_item"), 18 #Rule(LinkExtractor(allow=(r'https://movie.douban.com/tag/\[wW]+'))), # 从网页中提取http链接 19 20 ) 21 22 23 def parse_item(self, response): 24 movie = MovieItem() 25 movie['name'] = response.xpath('//*[@id="content"]/h1/span[1]/text()').extract()[0] 26 movie['director'] = '/'.join(response.xpath('//a[@rel="v:directedBy"]/text()').extract()) 27 movie['writer'] = '/'.join(response.xpath('//*[@id="info"]/span[2]/span[2]/a/text()').extract()) 28 movie['url'] = response.url 29 movie['score'] = response.xpath('//*[@class="ll rating_num"]/text()').extract()[0] 30 movie['collections'] = response.xpath('//span[@property="v:votes"]/text()').extract()[0] #评价人数 31 movie['pub_date'] = response.xpath('//span[@property="v:initialReleaseDate"]/text()').extract()[0] 32 movie['actor'] = '/'.join(response.css('span.actor span.attrs').xpath('.//a[@href]/text()').extract()) 33 movie['classification'] = '/'.join(response.xpath('//span[@property="v:genre"]/text()').extract()) 34 print('movie:%s |url:%s'%(movie['name'],movie['url'])) 35 return movie 36 37 def parse_start_url(self, response): 38 urls = response.xpath('//div[@class="article"]//a/@href').extract() 39 for url in urls: 40 if 'https' not in url: # 去除多余的链接 41 url = response.urljoin(url) # 补全 42 print(url) 43 print('*'*30) 44 yield scrapy.Request(url)