Scrapy官网上对rules的介绍不多,短短的几行关于类的参数说明,再加上一个代码示例。先把几个要点列出来:
class scrapy.contrib.spiders.
Rule
(link_extractor,callback=None,cb_kwargs=None,follow=None,process_links=None,process_request=None)
link_extractor是一个Link Extractor对象。 其定义了如何从爬取到的页面提取链接。
follow是一个布尔(boolean)值,指定了根据该规则从response提取的链接是否需要跟进。 如果callback 为None,follow 默认设置为True,否则默认为False。
然后还有一段重要的警告:
当编写爬虫规则时,请避免使用parse作为回调函数。 由于CrawlSpider使用parse方法来实现其逻辑,如果您覆盖了parse方法,crawl spider 将会运行失败。
官网上给出的配合rule使用CrawlSpider的例子:
import scrapy
from scrapy.contrib.spiders import CrawlSpider, Rule
from scrapy.contrib.linkextractors import LinkExtractor
class MySpider(CrawlSpider):
name = 'example.com'
allowed_domains = ['example.com']
start_urls = ['http://www.example.com']
rules = (
# 提取匹配 'category.php' (但不匹配 'subsection.php') 的链接并跟进链接(没有callback意味着follow默认为True)
Rule(LinkExtractor(allow=('category\.php', ), deny=('subsection\.php', ))),
# 提取匹配 'item.php' 的链接并使用spider的parse_item方法进行分析
Rule(LinkExtractor(allow=('item\.php', )), callback='parse_item'),
)
def parse_item(self, response):
self.log('Hi, this is an item page! %s' % response.url)
item = scrapy.Item()
item['id'] = response.xpath('//td[@id="item_id"]/text()').re(r'ID: (\d+)')
item['name'] = response.xpath('//td[@id="item_name"]/text()').extract()
item['description'] = response.xpath('//td[@id="item_description"]/text()').extract()
return item
初看这段代码及说明,心里有这样几个疑问:
1、没有parse()方法(及start_requests()方法),爬虫的入口方法是哪个?
2、Rule(LinkExtractor(allow=('category\.php', ), deny=('subsection\.php', ))),
没有callback 这里定义的Rule是哪个方法来处理?
3、示例代码中,爬虫新的url在哪里添加?
4、rules好像只要作定义就可以,不需要在配置文件里再进行配置。
对比之前Scrapy中写过的代码,处理的流程是,1)定义好爬虫的入口(包括start_urls),2)做好爬取过程中url的添加,(通常是列表页和分页),3)内容页字段的提取。现在使用了Rules,以上的步骤不一样了,但是这几步骤是如何实现的,需要探究一番。
我没有从源码中去深入了解,想通过代码的方式来快速测试,了解一下rules的一些使用方法。
实验:
定义爬虫的起始url 为 简书首页。
start_urls=['http://www.jianshu.com']
爬取rules定为简书的用户主页(/users/xxxx)和文章页(/p/xxxx)
rules = [
Rule(SgmlLinkExtractor(allow=(r'http://www.jianshu.com/users/[a-z0-9]+?'))),
Rule(SgmlLinkExtractor(allow=(r'http://www.jianshu.com/p/[a-z0-9]+?')), callback="parse_item"),
测试结果:
1、定义好rules后,Spider会自动管理url
2、以简书爬取为例,能自动管理的url包括文章页(articles),粉丝页(followers),最新动态页(timeline)... 还包含所有的分页。
结论和疑问:
1、rules很适合做全站内容的爬取。
2、要提取指定页面数据,rules要定义更准确些。(正则表达式)
3、定义rules之后如何做登录,还不太清楚。
重写start_requests()方法后,不清楚再如何调才能使用rules在爬虫中运转起来。是不适合有登录的爬取吗?
4、follow用法不太清楚。没有callback的rule是哪个方法在处理?