


摘 ?要:Python語言使用起來靈活方便,很適合爬取網絡數據并進行清洗及可視化。文章設計了一個Python爬蟲程序,先獲取到岳陽人才信息網的所有公開招聘信息,然后將信息保存到MongoDB數據庫,再從數據庫導出至Excel文件,再對Excel的數據使用正規表達式進行清選,最后使用Matplotlib模塊以圖像形式展現統計結果。數據統計基于薪酬、工作地點及學歷要求等三個維度,可以幫助求職者對于該網站招聘信息的價值做一個粗略的估計。
關鍵詞:Python;mongoDB;Excel;招聘信息;爬蟲
中圖分類號:TP391.1 ? ? ?文獻標識碼:A 文章編號:2096-4706(2020)15-0018-03
Abstract:Python language is flexible and convenient to use,which is very suitable for crawling network data and cleaning and visualization. This paper designs a Python crawler program,which first obtains all the open recruitment information of Yueyang talent information website,then the information is saved to mongoDB database,and then exported to Excel file from the database. The program uses the regular expression to clear the Excel data,and finally uses Matplotlib module to show the statistical results in the form of images. Data statistics are based on salary,workplace and education requirements,which can help job seekers to make a rough estimate of the value of the websites recruitment information.
Keywords:Python;mongoDB;Excel;recruitment information;crawler
0 ?引 ?言
使用Python語言編寫程序,幾行代碼就可以把初步結構化的數據入庫,而Java實現網絡爬蟲的代碼要比Python多很多,而且實現要復雜得多;Python語言生態環境的Urllib、Requests、Beautifulsoup等模塊可以輕松地構建一個基本的數據采集程序,而Java語言的爬蟲庫資源就要少得多[1]。關于Python語言的特點、網絡爬蟲的定義以及工作流程等等,張艷等人作出了清晰明白的解釋[2]。基于多年的學習與工作經驗,作者總結了多種數據爬取途徑:對靜態網頁使用Request模塊,對動態網頁采用Selenium模塊;簡單的數據爬取使用Python無框架代碼,復雜或大型的數據爬取使用Scrapy技術框架。該文結合Requests模塊采用Python無框架代碼制作了一個針對岳陽人才信息網(http://www.yyrcxx.com)的爬蟲程序。
1 ?數據爬取設計
爬蟲總體的設計如圖1所示。首先在瀏覽器中打開岳陽人才信息網,查看源代碼,分析其頁面結構;然后編寫Python無框架爬蟲代碼,下載其網頁數據;再是對數據進行清洗,提取出有用的部分存儲到MongoDB數據庫;接著從數據庫中的集合導出數據至Excel文檔,對此文檔的數據進行必要的整理;最后使用Jupyter Notebook編寫代碼調取Excel文檔數據,實現讀取、寫入Excel以及清洗、統計與圖表可視化操作。
1.1 ?頁面跳轉分析
Google公司的Chrome瀏覽器速度慢、界面簡單,建立書簽文件夾很方便,很多程序員都喜歡使用。在瀏覽器地址欄輸入www.yyrcxx.com然后回車,即可打開岳陽人才信息網主頁,在頁面頂部導航欄點擊“搜職位”,頁面跳轉到http://www.yyrcxx.com/jobs/,在打開的“職位”顯示頁面中部點擊“搜索”按鈕跳轉到新的頁面,這個新的頁面底部包含有“首頁”“上一頁”“1”“2”“3”……“下一頁”“尾頁”等頁面跳轉按鈕,其在地址欄顯示的地址信息為http://www.xbhrw.com/jobs/jobs-list.php?key=&jobcategory=&trade=&citycategory=&wage=&jobtag=&education=&experience=&settr=&nature=&scale=&sort=&page=1,可以發現只有page項有非空值,其他參數的值都為空,即網址的參數中只有page參數有用。據此,可以把網址信息簡化為http://www.xbhrw.com/jobs/jobs-list.php?page=1,使用簡化后的網址輸入到地址欄并按下回車鍵,發現頁面正常打開。令page=2,發現第2頁處于被選中狀態,于是,得到頁面跳轉的規律:通過讓page的數值每次加1,即可自動獲取下一個頁面的數據。由于岳陽人才信息網所列出的招聘信息并不多,截止作者抓取數據時只有29頁,這里不用設置任何篩選條件,可直接獲取網站的所有招聘信息。
1.2 ?數據存取設計
招聘數據整齊而有規律,這里采用非關系型數據庫MongoDB來存儲數據。首先,從MongoDB官網下載安裝文件,將之安裝到D盤(OS:Windows 7),使用命令在MongoDB命令行中新建數據庫jobs,并在jobs數據庫中新建數據表yyrcxx(在MongoDB中被稱為集合yyrcxx),在爬蟲下載器程序中使用語句client = pymongo.MongoClient('localhost', 27017)建立一個連接client,在程序中使用client[‘jobs]獲取jobs數據庫,使用client[‘jobs][‘yyrcxx]獲取yyrcxx集合(即關系型數據庫中的數據表)。
1.3 ?偽裝瀏覽器
HTTP協議是請求/響應模式,瀏覽器的Request Headers有一個重要的屬性就是User-Agent,在設計爬蟲程序時一定要設置User-Agent。在Chrome瀏覽器的地址欄輸入chrome: //version然后回車,在打開的頁面中找到“用戶代理”行,復制后面的User-Agent值。
1.4 ?頁面數據提取
使用Python 3進行網絡數據采集時,基于連接的穩定性考慮,一般不使用較為老舊的urllib.request模塊,而是使用更為方便的Requests模塊[3]。
這里,爬取岳陽人才網數據時,使用for n in range(1, 30)控制頁面的跳轉,range()函數的參數是左閉右開區間,這里的30不被包含,所以共有29頁。頁面定位使用語句baseUrl = 'http://www.yyrcxx.com/jobs/jobs-list.php?page=' + str(n);獲取頁面使用語句strhtml = requests.get(url, headers=headers),其中headers是一個字典,里面僅設置了屬性User-Agent。對獲取的頁面數據strhtml,使用BeautifulSoup進行解析,采用lxml選項分析頁面結構,對應代碼:soup = BeautifulSoup(strhtml.text, 'lxml'),然后使用soup對象的select()方法和find()方法進一步定位具體元素。比如語句company = item.find('div').find('div', class_='list-item item2 f-left').find('a').get_text(),表示在item頁面元素下面尋找第一個div標記元素,再在這第一個div標記元素下找到一個div標記元素,其class屬性的值至少包含有list-item、item2、f-left這三個值,再到當前div元素的下面尋找第一個a標記元素,然后取得這個a標記元素的文本。
1.5 ?實驗過程
硬件配置:CPU為Intel Core i5-4200M@2.50 GHz,Memory 12 GB。軟件配置:Windows 7 64 Bit,Anaconda 3下的Python 3.6.6,MongoDB shell version v4.0.13,PyCharm 2018.1。實驗步驟:第1步,進入MongoDB的安裝位置MongoDB文件夾,運行bin\mongod --dbpath data,其中data是程序員在MongoDB文件夾新建的用于保存數據的子文件夾;第2步,打開PyCharm,安裝MongoDB插件,在PyCharm的Mongo Explorer點擊“Connect to this server”按鈕,連接MongoDB數據庫;第3步,運行爬蟲主程序,下載網頁數據并存儲到MongoDB數據庫;第4步,編寫Python文件從MongoDB導出數據表內容到CSV文本文件;第5步,使用Windows系統自帶的記事本打開導出的CSV文件,并另存為ANSI編碼格式的同名文件;第6步,編寫Python代碼從CSV文件加載數據并導出Excel文件。
2 ?數據統計
此次實驗抓取了岳陽人才信息網自2018年4月4日至2020年6月15日14時的在線可見數據(經分析,該網站不定期會刪減一些數據),共計569條崗位招聘需求信息。根據求職者的主要參考項目如薪酬、工作地、學歷要求等,使用Python的可視化技術做成餅圖。為了方便代碼輸出,數據統計及可視化操作皆通過啟動Jupyter Notebook命令在瀏覽器(實驗采用Google Chrome 78.0.3904.108 64位版本)中查看。通過引入matplotlib.pyplot模塊實現數據的可視化,對于餅圖中的漢字,使用matplotlib.rcParams['font.sans-serif']=['SimHei']解決漢字亂碼現象。
2.1 ?薪酬數據統計及可視化
xlrd模塊用于Excel文件的讀取,將之前從MongoDB中導出到Excel的文件,再次加載到Python中,通過from collections import Counter引入Counter計數模塊,再使用counts = (dict)(Counter(pay))把pay列表先轉為Counter對象,再變為字典對象,最終得到字典數據{'5000~10000元/月': 247, '2000~3000元/月': 42, '3000~5000元/月': 245, '1萬以上/月': 30, '1500~2000元/月': 5},合計569條數據,如圖2所示。
'1500~2000元/月'占比0.88%,'2000~3000元/月'占比7.38%,'3000~5000元/月'占比43.06%,'5000~10000元/月'占比43.41%, '1萬以上/月'占比5.27%。數據表明,5000元以上月工資占比48.68%,3 000元以上的月工資合計占比91.74%,3 000元以下的月工資則只有8.26%。
2.2 ?工作地點統計
工作地點的統計方式與薪酬數據統計相同,最終獲得字典數據:{'岳陽市': 33, '經濟技術開發區': 9, '岳陽市/經濟技術開發區': 33, '湖南省/岳陽樓區': 1, '岳陽市/岳陽樓區': 88, '岳陽樓區': 25, '湖南省/岳陽市': 112, '岳陽市/南湖新區': 10, '岳陽市/平江縣': 2, '岳陽市/華容縣': 4, '岳陽市/岳陽縣': 2, '岳陽市/君山區': 2, '岳陽市/云溪區': 14, '岳陽市/臨湘市': 4, '岳陽市/城陵磯新港區': 32, '岳陽市/汨羅市': 19, '臨湘市': 2, '汨羅市': 8, '湖南省/長沙市': 24, '湖南省': 133, '天津市/塘沽區': 1, '湖北省/咸寧市': 1, '福建省/廈門市': 1, '四川省': 1, '云南省': 1, '黑龍江省/綏化市': 1, '河南省': 1, '福建省/泉州市': 1, '湖北省/武漢市': 2, '廣東省/深圳市': 2}。
在此字典基礎上根據距離遠近進一步歸納,將其合并為5類:{'岳陽市外城': 89, '岳陽市內城': 311, '湖南省': 133, '湖南省外': 12, '湖南省/長沙市': 24},其中'岳陽市內城'包括:{'經濟技術開發區', '湖南省/岳陽市', '岳陽市', '岳陽市/岳陽樓區', '岳陽市/經濟技術開發區', '岳陽市/南湖新區', '岳陽樓區', '湖南省/岳陽樓區'},'岳陽市外城'包括:{'岳陽市/臨湘市', '臨湘市', '岳陽市/君山區', '岳陽市/云溪區', '岳陽市/汨羅市', '汨羅市', '岳陽市/岳陽縣', '岳陽市/平江縣', '岳陽市/華容縣', '岳陽市/城陵磯新港區'}。根據該數據繪制的餅圖如圖3所示。
'岳陽市內城'311個地點計數,占569個地點總數的比例為54.66%;'岳陽市外城'89個地點計數,占比15.64%。岳陽地區合計400個地點計數,共占比例為70.30%;'湖南省/長沙市'24個地點計數,占比4.22%;'湖南省'133個地點計數,占比23.37%。湖南省內合計557個地點計數,共占比例為97.89%;湖南省外,列表['天津市/塘沽區': 1, '湖北省/咸寧市': 1, '福建省/廈門市': 1, '四川省': 1, '云南省': 1, '黑龍江省/綏化市': 1, '河南省': 1, '福建省/泉州市': 1, '湖北省/武漢市': 2, '廣東省/深圳市': 2],合計12個地點計數,占比2.11%。
2.3 ?學歷要求統計
通過import re導入正則表達式,設置pattern = r'.*招聘人數:(.+)人.*' 清洗Excel文件eduRequ字段中“招聘人數:1人”字樣文本內容,設置patt_edu = r'^學歷要求:(.{2,5})\?\?\|\?\?'清洗eduRequ字段中“學歷要求:大專??|??工作經驗:3-5年”字樣文本內容。最終得到edu_dict字典對象{'初中': 2690, '高中': 417, '中技/中專': 266, '中專': 132, '中技': 54, '大專': 515, '本科': 195, '碩士': 2},共計4 271個工作崗位。合并中技、中專學歷為1個類別,得到餅圖如圖4所示。
計算可知,招聘學歷要求中,初中文化占比62.98%;高中文化占比9.76%;列表['中技/中專': 266, '中專': 132, '中技': 54]合計452人,占比10.58%;大專文化占比12.06%;本科文化占比4.57%;碩士文化占比0.05%。可以看出,初等教育水平(僅包含初中)占比62.98%,大約2/3;中等教育水平(高中、中技及中專)占比20.34%,大約1/5;高等教育水平(大專、本科、碩士)占比16.68%,大約1/6。數據表明,岳陽人才信息網所發布的公開招聘信息對于學歷的要求總體不高。
2.4 ?各學歷平均工資
引入xlwt模塊,可實現Excel文件的寫入功能。在Excel中,首先將'3000~5000元/月'設為3 000,其他薪酬類似處理,將文字轉為數字,得到工資字典:{'碩士': 10000, '本科': 4851, '大專 ': 4166, '中專/中技': 5459, '高中': 3654, '初中': 3904}。將每類學歷的人數與薪酬相乘,累加后再求平均。最后綜合各種可能性,可以單純地就某一個方面進行預測(數學期望)。將各種學歷的平均工資乘以其出現的比例(概率),可以給出任意一個求職者的薪酬估計:10 000×0.05% +4 851×4.57%+4 166×12.06%+5 459×10.58%+3 654×9.76%+3 904×62.98%=4 122.04(元)。
數據表明,中專/中技學歷者5 459元的工資高于大專學歷者4 166元的工資,初中學歷者3 904元的工資高于高中學歷者3 654元的工資。因此,該人才招聘市場勞動力供求方面,對中專、中技與初中學歷者需求旺盛,從而佐證該地區勞動密集型、低端加工及商貿服務企業較多。
3 ?結 ?論
作者通過對岳陽人才網的招聘信息實施爬取實驗,得到了薪酬、工作地點及學歷這3個維度的分類統計數據,并區分各種學歷計算出其平均工資以及該網站所有招聘崗位的薪酬期望。下一步可以開展的工作:一是選取更多維度對招聘信息進行統計分析;二是建立數學模型,使用人工神經網絡的方法對該網站招聘信息進行統計分析和結果預測。
參考文獻:
[1] 鴿子.為什么用Python實現網絡爬蟲而不用java [EB/OL].(2020-06-21).https://www.yisu.com/zixun/145468.html.
[2] 張艷,吳玉全.基于Python的網絡數據爬蟲程序設計 [J].電腦編程技巧與維護,2020(4):26-27.
[3] 黑羊的皇冠.Python爬蟲基礎之urllib與requests [EB/OL].(2018-03-09).https://www.jianshu.com/p/1efa672156d3.
作者簡介:申麗平(1982—),男,漢族,湖南邵東人,講師,碩士,主要研究方向:數據科學。