分析爬取對象
初始網址,
http://hr.tencent.com/position.php?@start=0&start=0#a
(可選)由於含有多頁數據,我們可以查看一下這些網址有什么相關
![]()
page2:http://hr.tencent.com/position.php?@start=0&start=10#a
page3:http://hr.tencent.com/position.php?@start=0&start=20#a
也就是說末尾id每次遞增10(#a無實際意義,輸入start=0也能進入第一頁)。
確定想爬取的信息:

我們爬取表格中的5類信息和每個招聘的具體網頁地址,共6個條目,在查看源碼的過程中我們可以使用F12開發者工具輔助定位,

其中class=event的tr表示白色背景條目,class=odd表示灰色背景條目,點擊開查看具體信息如下,

爬蟲編寫
使用框架初始化項目,
scrapy startproject Tencent

修改items.py,對應上面需要記錄的六組數據,
import scrapy
class TencentItem(scrapy.Item):
# define the fields for your item here like:
# name = scrapy.Field()
# 職位名
positionName = scrapy.Field()
# 職位詳情鏈接
positionLink = scrapy.Field()
# 職位類別
positionType = scrapy.Field()
# 招聘人數
peopleNumber = scrapy.Field()
# 工作地點
workLocation = scrapy.Field()
# 發布時間
publishtime = scrapy.Field()
生成初始爬蟲spider命名為tensent.py,
scrapy genspider tencent "tencent.com"
修改tencent.py,注意函數需要返回item
import scrapy
from Tencent.items import TencentItem
class TencentSpider(scrapy.Spider):
name = "tencent"
allowed_domains = ["tencent.com"]
baseURL = "http://hr.tencent.com/position.php?@start="
offset = 0
start_urls = [baseURL + str(offset)]
def parse(self, response):
node_list = response.xpath("//tr[@class='even'] | //tr[@class='odd']")
for node in node_list:
item = TencentItem()
# 職位名
item['positionName'] = node.xpath("./td[1]/a/text()").extract()[0]
print(node.xpath("./td[1]/a/text()").extract())
# 職位詳情鏈接
item['positionLink'] = node.xpath("./td[1]/a/@href").extract()[0]
# 職位類別
if len(node.xpath("./td[2]/text()")):
item['positionType'] = node.xpath("./td[2]/text()").extract()[0]
else:
item['positionType'] = ''
# 招聘人數
item['peopleNumber'] = node.xpath("./td[3]/text()").extract()[0]
# 工作地點
item['workLocation'] = node.xpath("./td[4]/text()").extract()[0]
# 發布時間
item['publishtime'] = node.xpath("./td[5]/text()").extract()[0]
yield item
# 換頁方法一:直接構建url
if self.offset <2190:
self.offset += 10
url = self.baseURL + str(self.offset)
yield scrapy.Request(url, callback=self.parse) # callback函數可以更換,即可以使用不同的處理方法處理不同的頁面
兩個yield連用使得不同的調用次數函數輸出不同的表達式,這是一個很好的技巧,不過第二個yield是可以替換為return的,畢竟提交一個新請求后引擎會自動調用parse去處理響應
這里面使用提取下一頁的方法是自己拼接之后的網址,這是一種相對而言笨拙一點的手法,一般會直接在網頁中提取下一頁的網址,但是這對於一些無法提取下一頁網址的情況很實用。
更新一下直接在網頁提取下一頁的方法,
# 換頁方法二:提取下頁鏈接
if not len(response.xpath("//a[@class='noactive' and @id='next']")):
url = 'http://hr.tencent.com/' + response.xpath("//a[@id='next']/@href").extract()[0]
yield scrapy.Request(url, callback=self.parse)
對於靜態頁面這很容易,但是如果是動態頁面就可能需要其他的輔助手段了。另外settings中有有關請求頭文件的設置部分,有需求的話可以改寫之。
取消settings.py對於管線文件的注釋,

修改pipelines.py文件,
import json
class TencentPipeline(object):
def __init__(self):
self.f = open('tencent.json','w')
def process_item(self, item, spider):
content = json.dumps(dict(item),ensure_ascii=False) + ',\n'
self.f.write(content)
return item
def close_spider(self,spider):
self.f.close()
這樣一個初級的爬蟲項目就完成了。
測試並運行,
scrapy check tencent
scarpy srawl tencent
打開保存的json文件,可以看到類似下面的輸出,每一行為一條招聘信息,
{"workLocation": "深圳", "positionType": "技術類", "positionName": "24111-安全架構師", "peopleNumber": "1", "publishtime": "2017-08-26", "positionLink": "position_detail.php?id=32378&keywords=&tid=0&lid=0"},
完成后整個文件夾變化如下,

實際爬取過程是要消耗一點時間的。
