建立CrawlSpider
模板 scrapy genspider -t crawl <爬蟲名字> <域名>
php
模板代碼示例:正則表達式
# -*- 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
dom
CrawlSpider使用rules來定義爬蟲的爬取規則,並將匹配後的url自動拼接完整構形成請求提交給引擎。因此在正常狀況下,CrawlSpider不須要單獨手動返回請求了。scrapy
在rules中包含一個或多個Rule對象,每一個Rule對爬取網站的動做定義了某種特定操做,好比提取當前相應內容裏的特定連接,是否對提取的連接跟進爬取,對提交的請求設置回調函數等。ide
若是多個rule匹配了相同的連接,則根據規則在本集合中被定義的順序,第一個會被使用。函數
Rule
對象的參數網站
LinkExtracto
連接提取器,用於提取須要爬取的連接ui
callback
回調函數,提取的url請求對應的響應的處理函數,函數名是一個字符型url
注意:當編寫爬蟲規則時,避免使用parse做爲回調函數。因爲CrawlSpider使用parse方法來實現其邏輯,若是覆蓋了 parse方法,crawl spider將會運行失敗。spa
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
是同樣的