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)

 

posted @ 2017-05-03 16:34  zhangjpn  阅读(9821)  评论(1编辑  收藏  举报