本人最近由於失業,需要求職,去了很多求職網站,特發其想,想知道現在的人才市場行情,所以寫了個爬蟲來了解一下。
*本爬蟲用於學習交流使用,請勿用於商業用途,使用時請遵守第三方網站的相關要求。
由於近期主要在BOSS直聘上投簡歷,而大多的回覆都是在BOSS直聘上的,所以突發其想,就去研究一下上面的市場狀況
前期說明:
本爬早用到的庫有如下:
requests:這個是獲取響應對象的
lxml:用lxml+xpath快速可以獲取相要的內容,速度比BeautifulSoup快
pandas:將獲取到的內容保存爲csv文件,而且用pandas的話,可以節省幾行代碼
time:爬蟲在爬取過程中需要休眠,減輕網站壓力
現在正式開始爬蟲:
第一步:導入相對應的包
# Power by JackyHon 2018-09-13
# 文件僅供學習使用,他用無效
# 使用時請遵守第三方網站的規定或查看robots.txt
import requests
from lxml import etree
import pandas as pd
import time
第二步:爲了給代碼解耦,所以將獲取網站response對象(如果不知道什麼是response對象的話,真心要百度一下再學爬蟲吧)的功能封裝在一起。其次,按照慣例還是創建一個head信息,模擬瀏覽器行爲。這段代碼有個心比較大的地方,就是exception,這裏我直接寫Exception,只要出錯就退出。
# 獲取網站對象的函數,獲取boss直聘上的信息
def spider(query, page):
query = query
# 創造headers
head = {'User-Agent': "Mozilla/5.0 (Windows NT 6.1; Win64; x64) "
"AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.90 Safari/537.36"}
while True:
try:
# 構造需要爬取的URL,由於後續需要使用lxml,所以需要轉換編碼utf8
url = 'https://www.zhipin.com/c101280100/h_101280100/?query={0}&page={1}'.format(query, page)
response_obj = requests.get(url=url, headers=head)
response_obj.encoding = 'utf8'
return response_obj
except Exception:
print('-'*20 + '退出搜索'+'-'*20)
break
第三步:對獲取的response對象做解釋,獲取我想要的數據
因爲我是剛用xpath,所以不是太熟悉,但是用了之後覺得xpath真是太好用了,速度快,爬取路徑直觀,比BeautifulSoup效率高,當然,也是有一定學習成本。
def get_data(response_obj):
detail = []
# 爲了構造職位詳細信息的URL前綴
front_url = 'https://www.zhipin.com'
html = etree.HTML(response_obj.text, parser=etree.HTMLParser(encoding='utf-8'))
# 獲取職位名稱
job_title = html.xpath("//div[@class='job-title']/text()")
# 獲取薪水範圍
salary = html.xpath("//span[@class='red']/text()")
# 獲取公司名稱
company = html.xpath("//div[@class='company-text']/h3/a/text()")
# 獲取地區,經驗,學位
area_ex_degree = html.xpath("//div[@class='info-primary']/p/text()")
# 獲取職位詳情URL後綴,後期需要用front_url+後綴組合成完成的職位詳情URL
link = html.xpath("////div[@class='info-primary']/h3/a/@href")
# 詳情分組
for i in range(0, len(area_ex_degree), 3):
detail.append(area_ex_degree[i:i+3])
# 獲取發佈時間
date_of_issue = html.xpath("//div[@class='info-publis']//p/text()")
# 以字典形式返回結果
return {'job_title': job_title,
'salary': salary,
'company': company,
'detail': detail,
'publish_date': date_of_issue,
'detail_link': [front_url+i for i in link]
}
第四步:主要的功能模塊編寫完畢,然後就是到主程序這塊了。由於需要連續獲取網頁信息,所以主程序中需要有循環控制。由於BOSS直聘上搜索任何關鍵詞,最多返回10頁的搜索結果,而問題就在於如何判斷是最後一頁,所以這裏用到
if set(result['company']) > set(get_data(obj)['company'])
來判斷最後一頁爬取的是否已經爬取過,如果是則退出程序;如果不是則添加進結果,程序繼續爬取。
# 啓動爬蟲
if __name__ == '__main__':
# 儲存爬取結果
result = None
# 循環標記
flag = True
# 從第1頁開始
pg = 1
# 輸入需要搜索的職位關鍵字
words = input('請輸入需要搜索的關鍵字:')
while flag:
obj = spider(words, pg)
if result is None:
print('第{}頁'.format(pg))
result = get_data(obj)
print(result.keys(), ":", result.values())
else:
if set(result['company']) > set(get_data(obj)['company']):
flag = False
print('程序結束')
else:
print('第{}頁'.format(pg))
for key, value in get_data(obj).items():
result[key].extend(value)
print(key, ":", value)
pg = pg + 1
# 爲了減輕服務器負擔,所以選擇休眠3秒
time.sleep(3)
data = pd.DataFrame(result)
data.to_csv('{}.csv'.format(words), encoding='gbk')
最後,程序會將爬取的結果保存爲CSV文件,爲什麼保存CSV呢?因爲人家給你撐死才300條數據啊,還用鬼數據庫啊?
針對爬取的結果,可以自己再做數據歸納整理。後面若我有空的話,會繼續補充。多多交流!
後記:
其實這個爬蟲可以用scrapy寫,但是如果用scrapy的話,就整個功能基本寫好了,猶其是保存數據部分,真心方便,缺少了思考,所以最後還是用最原始的方法嘗試。本人水平一般,請多多見諒!