crawlSpider
创建
CrawlSpider
模板scrapy genspider -t crawl <爬虫名字> <域名>
-
模板代码示例:
# -*- coding: utf-8 -*-
import scrapy
from scrapy.linkextractors import LinkExtractor
from scrapy.spiders import CrawlSpider, Rule
class XxxSpider(CrawlSpider):
name = 'xxx'
allowed_domains = ['www.baidu.com']
start_urls = ['http://www.baidu.com'] rules = (
Rule(LinkExtractor(allow=r'Items/'), callback='parse_item', follow=True),
)
def parse_item(self, response):
i = {}
#i['domain_id'] = response.xpath('//input[@id="sid"]/@value').extract()
#i['name'] = response.xpath('//div[@id="name"]').extract()
#i['description'] = response.xpath('//div[@id="description"]').extract()
return i CrawlSpider
继承自Spider
类,除了(name, allowed_domains, start_urls)之外,还定义了rules
rules
CrawlSpider使用rules来定义爬虫的爬取规则,并将匹配后的url自动拼接完整构造成请求提交给引擎。所以在正常情况下,CrawlSpider不需要单独手动返回请求了。
在rules中包含一个或多个Rule对象,每个Rule对爬取网站的动作定义了某种特定操作,比如提取当前相应内容里的特定链接,是否对提取的链接跟进爬取,对提交的请求设置回调函数等。
如果多个rule匹配了相同的链接,则根据规则在本集合中被定义的顺序,第一个会被使用。
-
Rule
对象的参数LinkExtracto
链接提取器,用于提取需要爬取的链接-
callback
回调函数,提取的url请求对应的响应的处理函数,函数名是一个字符型注意:当编写爬虫规则时,避免使用parse作为回调函数。由于CrawlSpider使用parse方法来实现其逻辑,如果覆盖了 parse方法,crawl spider将会运行失败。
follow
是否跟进链接,True
表示跟进,就是在请求的url页面,有满足这个规则的url会被继续提取,然后组成Request发送跟调度器排队继续请求process_links
:指定该spider中哪个的函数将会被调用,从link_extractor中获取到链接列表时将会调用该函数。该方法主要用来过滤。process_request
:指定该spider中哪个的函数将会被调用, 该规则提取到每个request时都会调用该函数。 (用来过滤request)
-
LinkExtractor
allow
:满足括号中正则表达式的URL会被提取,如果为空,则全部匹配。deny
:满足括号中正则表达式的URL一定不提取(优先级高于allow)。allow_domains
:会被提取的链接的domains。deny_domains
:一定不会被提取链接的domains。restrict_xpaths
:使用xpath表达式,和allow共同作用过滤链接。
案例
crawlSpider
爬取腾讯招聘
# -*- coding: utf-8 -*-
import scrapy
from scrapy.linkextractors import LinkExtractor
from scrapy.spiders import CrawlSpider, Rule
from craw_spider.items import PositionItem, DetailItem
class HrSpider(CrawlSpider):
name = 'hr'
allowed_domains = ['hr.tencent.com']
start_urls = ['https://hr.tencent.com/position.php?start=0']
rules = (
# 提起职位基本信息规则
Rule(LinkExtractor(allow=r'position\.php\?&start=\d+#a'),
callback='parse_item',
follow=True),
# 提取职位详情页规则
Rule(LinkExtractor(allow=r'position_detail\.php\?id=\d+'),
callback='parse_detail',
follow=False),
)
def parse_item(self, response):
item = PositionItem()
trs = response.xpath(
'//table[@class="tablelist"]/tr[@class="even"] | //table[@class="tablelist"]/tr[@class="odd"]')
for tr in trs:
item['position_name'] = tr.xpath('./td/a/text()').extract_first()
item['position_type'] = tr.xpath('./td[2]/text()').extract_first()
item['position_num'] = tr.xpath('./td[3]/text()').extract_first()
item['position_addr'] = tr.xpath('./td[4]/text()').extract_first()
item['publish_data'] = tr.xpath('./td[5]/text()').extract_first()
yield item
def parse_detail(self, response):
item = DetailItem()
item['position_require'] = response.xpath('//table[@class="tablelist textl"]/tr[3]/td/ul/li//text()').extract()
item['position_duty'] = response.xpath('//table[@class="tablelist textl"]/tr[4]/td/ul/li//text()').extract()
yield item
其他组件的使用和
Spider
是一样的