写在前面
这周临时通知出差,所以没办法更文,实在抱歉。
还有一件很重要的事情,咸鱼 下周二 有一场 自费赠书 ,一共6本,全部都是咸鱼自掏腰报回馈粉丝的福利。
目前暂定在 交流群 和 公众号后台 分别抽奖,按照上次的抽奖结果,交流群的中奖概率为1/30,后台小程序的中奖概率为1/100。所以还没有加入 交流群 的朋友快点加入吧~
为什么使用CrawlSpider类?
回顾上一篇文章,我们大多时间都是在寻找下一页的url地址或者是内容的url地址上面,我们的大体思路是这样的:
从response中提取所有的a标签对应的url地址
自动的构造自己requests请求,发送给引擎
其实我们可以使用CrawlSpider类,让满足某个条件的url地址,我们才发送给引擎,同时能够指定callback函数。
CrawlSpider的使用
使用 scrapy genspider –t crawl [爬虫名] [all_domain] 就可以创建一个CrawlSpider模版。
CrawlSpider继承于Spider类,除了继承过来的属性外(name、allow_domains),还提供了新的属性和方法:
RulesCrawlSpider使用rules来决定爬虫的爬取规则,并将匹配后的url请求提交给引擎。所以在正常情况下,CrawlSpider不需要单独手动返回请求了。
在Rules中包含一个或多个Rule对象,每个Rule对爬取网站的动作定义了某种特定操作,比如提取当前相应内容里的特定链接,是否对提取的链接跟进爬取,对提交的请求设置回调函数等。
如果多个Rule匹配了相同的链接,则根据规则在本集合中被定义的顺序,第一个会被使用。
class?scrapy.spiders.Rule( ????????link_extractor, ????????callback?=?None, ????????cb_kwargs?=?None, ????????follow?=?None, ????????process_links?=?None, ????????process_request?=?None )
其中:
link_extractor:是一个Link Extractor对象,用于定义需要提取的链接。
callback: 从Link Extractor中每获取到链接时,参数所指定的值作为回调函数,该回调函数接受一个response作为其第一个参数。? 注意:当编写爬虫规则时,避免使用parse作为回调函数。由于CrawlSpider使用parse方法来实现其逻辑,如果覆盖了 parse方法,crawl spider将会运行失败。
follow:是一个布尔(boolean)值,指定了根据该规则从response提取的链接是否需要跟进。 如果callback为None,follow 默认设置为True ,否则默认为False。
process_links:指定该spider中哪个的函数将会被调用,从link_extractor中获取到链接列表时将会调用该函数。该方法主要用来过滤。
process_request:指定该spider中哪个的函数将会被调用, 该规则提取到每个request时都会调用该函数。(用来过滤request)
LinkExtractorsLink Extractors 的目的很简单:提取链接?
class?scrapy.linkextractors.LinkExtractor( ????allow?=?(), ????deny?=?(), ????allow_domains?=?(), ????deny_domains?=?(), ????deny_extensions?=?None, ????restrict_xpaths?=?(), ????tags?=?('a','area'), ????attrs?=?('href'), ????canonicalize?=?True, ????unique?=?True, ????process_value?=?None )
其中:
allow:满足括号中正则表达式的URL会被提取,如果为空,则全部匹配。
deny:满足括号中“正则表达式”的URL一定不提取(优先级高于allow)。
allow_domains:会被提取的链接的domains。
deny_domains:一定不会被提取链接的domains。
restrict_xpaths:使用xpath表达式,和allow共同作用过滤链接。
CrawlSpider类-实战腾讯招聘
上一篇文章我们用scrapy spider类实现了腾讯招聘的爬取,这次就再用CrawlSpider再实现一次。
创建爬虫scrapy?genspider?–t?crawl?tthr?tencent测试数据分析页面
这里我们只要找出详情页的链接规律和翻页的链接规律,所以可以找到以下链接:
#?详情页规律 position_detail.php?id=43310&keywords=&tid=0&lid=0 #?翻页规律 position.php?&start=10#a
到这里我们就可以写出以下rule:
#?详情页链接规律 Rule(LinkExtractor(allow=r'position_detail\.php\id=\d+&keywords=&tid=0&lid=0'),callback='parse_item'), #?在列表页查找翻页链接规律 Rule(LinkExtractor(allow=r'position\.php\?&start=\d+#a'),?follow=True)
注意: 在查找详情页Rule时follow=False,我们无需在详情页再查找详情页的地址,而在列表Rule时follow=False,意味着不断在列表页中查找下一页地址。
编写代码#?-*-?coding:?utf-8?-*- import?scrapy from?scrapy.linkextractors?import?LinkExtractor from?scrapy.spiders?import?CrawlSpider,?Rule from?tencenthr.items?import?TtItem class?TthrSpider(CrawlSpider): ????name?=?'tthr' ????allowed_domains?=?['tencent测试数据'] ????start_urls?=?['https://hr.tencent测试数据/position.php'] ????rules?=?( ????????Rule(LinkExtractor(allow=r'position_detail\.php\?id=\d+&keywords=&tid=0&lid=0'),?callback='parse_item'), ????????Rule(LinkExtractor(allow=r'position\.php\?&start=\d+#a'),?follow=True) ????) ????def?parse_item(self,?response): ????????item?=?TtItem() ????????item['sharetitle']?=?response.xpath('//td[@id="sharetitle"]/text()').extract_first() ????????item['category']?=?response.xpath('//span[text()="职位类别:"]/text()').extract_first() ????????item['location']?=?response.xpath('//span[text()="工作地点:"]/text()').extract_first() ????????item['num']?=?response.xpath('//span[text()="招聘人数:"]/text()').extract_first() ????????item['duty']?=?response.xpath('//div[text()="工作职责:"]/ul/li/text()').extract() ????????item['claim']?=?response.xpath('//div[text()="工作要求:"]/ul/li/text()').extract() ????????return?item本文全部代码已发布在github,点击原文即可获取~ 结果截图
控制台截图
数据库截图
查看更多关于Scrapy Crawlspider的详解与项目实战的详细内容...