【ML專案】基於網路爬蟲和資料探勘演算法的web招聘資料分析(一)——資料獲取與處理
前言
這個專案是在學校做的,主要是想對各大招聘網站的招聘資料進行分析,沒準能從中發現什麼,這個專案週期有些長,以至於在專案快要結束時發現網上已經有了一些相關的專案,我後續會把相關的專案材料放在我的GitHub上面,連結為:https://github.com/roguesir ,專案主要分為以下幾項:資料獲取與處理、探索性資料分析、資料探勘演算法建模等,這篇blog先介紹資料獲取與處理。
資料獲取
系統環境
Mac OS系統,python3.6
網站分析
各個招聘網站的結構不同,進行正則匹配的方式也不同,本專案供爬取了前程無憂、智聯招聘、拉勾網等多家招聘網站的web資料,以51job為例進行介紹:
前程無憂的招聘頁面如下圖所示,專案最終想要得到的資料包括崗位名稱、工作地點、薪資待遇、崗位介紹、公司性質等資訊,實際上需要兩次爬取頁面,第一次爬取搜尋頁面獲得URL,第二次通過URL爬取相關資訊。第一次使用Python的urllib和requests庫實現,第二次使用Python的BeautifulSoup庫實現。
爬蟲編寫
起初的爬蟲程式碼設定如下
# -*- coding:utf-8 -*-
from bs4 import BeautifulSoup
import sys
import importlib
importlib.reload(sys)
def get_html_page(lst,html):
res = requests.get(html)
res.encoding = 'gbk'
soup = BeautifulSoup(res.text, 'html.parser')
for job in soup.select('.tHjob' ):
position = job.select('h1')[0]['title']
print(position)
lst.append(position)
location = job.select('.lname')[0].text
lst.append(location)
salary = job.select('strong')[0].text
lst.append(salary)
companyname = job.select('a')[0]['title']
if len(companyname) > 0:
lst.append(companyname)
property = job.select('.ltype')[0].text
lst.append(property)
for comp in soup.select('.tCompany_main'):
experience = comp.select('.sp4')[0].text
lst.append(experience)
education = comp.select('.sp4')[1].text
lst.append(education)
number = comp.select('.sp4')[2].text
lst.append(number)
introduce = comp.select('.tmsg')[0].text
lst.append(introduce)
return lst
def write_txt(content):
with open('raw-cs-info1.txt','a') as f:
for item in content:
f.write(item+'\n')
def main():
print('running main')
for url in open('web-mis-url1-1.txt'):
print(url)
lst = []
content = get_html_page(lst, url)
write_txt(content)
print('Finished!')
main()
後來發現對於個別網頁,這樣跑會掛掉,有的匹配不成功就會出問題,於是將程式碼做了修改:
try:
for job in soup.select('.tHjob'):
position = job.select('h1')[0]['title']
print(position)
if len(position)<1:
lst.append(discribe[0])
else:
lst.append('null')
except:
lst.append('null')
上面的程式碼實現了對出現問題的匹配進行異常捕獲,出現異常的匹配直接在文字中寫入null,而不會中斷程式,對每個屬性進行設定,最終只需要對文字中的null進行處理就OK了。
資料處理
基本預處理
爬蟲爬下來的資料基本上還算乾淨,只有個別的匹配出現失誤,這可能由於網站html標籤不規則導致,這個問題在爬取前程無憂時候出現了,在智聯招聘等網站沒有出現。
# coding=utf-8
import re
with open('new098.txt','a') as f:
for line in open('cs-job-discribe.txt'):
new_line = line.replace('<br>','')
new_line = re.sub(r'<.+>','',line)
new_line = re.sub(r'[0-9][0-9]\-[0-9][0-9].+','',new_line)
f.write(new_line)
'''
if len(new_line)==1:
new_line = re.sub(r'\s',',',new_line) # 將樣本中的\空格\t\v\n\f等用','替換
f.write(new_line)
'''
網頁html中本身帶有的\空格\v\f\t\n等,寫入文件會顯示,因此需要進行預處理,把爬取下來的資料規範化。
資料重複問題:
由於專案是從不同的招聘網站上爬取資料,存在同一條招聘資訊出現多次的情況,需要進行去重處理,另外,全部資訊儲存在cs-info.xlsx檔案中,另將每個屬性的資料儲存在txt檔案中,其中存在大量重複資料需要進行去重處理。
總結
在此過程中出現的一些問題進行說明:
(1)編碼問題:在設定了utf-8編碼的情況下,爬取儲存的資料仍然會出現亂碼現象,需要設定html.decode=’gbk’才能解決。
(2)使用時也嘗試了用requests和urllib庫實現匹配提取,這個用在崗位描述資訊匹配上比較好,程式碼如下:
import re
import requests
import urllib
res = requests.get(html)
res.encoding = 'gbk'
try:
a = urllib.urlopen(html)
html = a.read()
html = html.decode('gbk')
reg = re.compile(r'<div class="bmsg job_msg inbox.*?<br>(.*?)<div class="mt10">',re.S)
discribe = re.findall(reg,html)
print discribe[0]
# print(discribe)
lst.append(discribe[0])
except:
lst.append('null')