本次因此的要求來自:https://edu.cnblogs.com/campus/gzcc/GZCC-16SE2/homework/3075html
前言python
本次做業是爬取拉勾網python相關崗位的信息,經過爬取崗位id、城市、公司全名、福利待遇、工做地點、學歷要求、工做類型、發佈時間、職位名稱、薪資、工做年限等數據並對其進行數據分析從而得出相應結論。json
網頁爬蟲網頁爬蟲
1.代理IPapi
在爬取數據以前咱們能夠考慮使用代理ip進行爬取,因此這裏我寫了一段代碼檢測ip的有效性,這裏我使用的是西刺免費代理ip進行測試。不過在測試中我發現可用的免費代理ip少之又少,而且時效性較短,用起來不太方便,因此若是有專門的爬蟲需求的人能夠考慮使用付費ip。cookie
測試代理ip時效性代碼以下:session
import requests import random proxies = {'http': ''} def loadip(): url='https: // proxy.horocn.com / api / proxies?order_id = 3JXK1633928414619951 & num = 20 & format = text & line_separator = win & can_repeat = yes' req=requests.get(url) date=req.json() ipdate2=date['msg'] global ipdate ipdate.extend(ipdate2) print(ipdate) def getproxies(): b=random.choice(ipdate) d = '%s:%s' % (b['ip'], b['port']) global proxies proxies['http']=d global msg msg=b loadip() getproxies() print(proxies)
2.拉勾網python相關崗位爬蟲app
測試完代理IP以後,咱們就能夠開始正式對拉勾網python相關崗位的信息進行爬蟲了。拉勾網python相關崗位網頁爬蟲代碼以下所示:運維
(注意:在下面的 ip_list 中的代理IP到如今爲止應該已經失效了,因此若是還要使用代理IP的話須要從新找新的代理IP)dom
1 # encoding: utf-8 2 import json 3 import requests 4 import xlwt 5 import time 6 import random 7 8 def GetUserAgent(): 9 ''' 10 功能:隨機獲取HTTP_User_Agent 11 ''' 12 user_agents=[ 13 "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; AcooBrowser; .NET CLR 1.1.4322; .NET CLR 2.0.50727)", 14 "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0; Acoo Browser; SLCC1; .NET CLR 2.0.50727; Media Center PC 5.0; .NET CLR 3.0.04506)", 15 "Mozilla/4.0 (compatible; MSIE 7.0; AOL 9.5; AOLBuild 4337.35; Windows NT 5.1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)", 16 "Mozilla/5.0 (Windows; U; MSIE 9.0; Windows NT 9.0; en-US)", 17 "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0; .NET CLR 3.5.30729; .NET CLR 3.0.30729; .NET CLR 2.0.50727; Media Center PC 6.0)", 18 "Mozilla/5.0 (compatible; MSIE 8.0; Windows NT 6.0; Trident/4.0; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; .NET CLR 1.0.3705; .NET CLR 1.1.4322)", 19 "Mozilla/4.0 (compatible; MSIE 7.0b; Windows NT 5.2; .NET CLR 1.1.4322; .NET CLR 2.0.50727; InfoPath.2; .NET CLR 3.0.04506.30)", 20 "Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN) AppleWebKit/523.15 (KHTML, like Gecko, Safari/419.3) Arora/0.3 (Change: 287 c9dfb30)", 21 "Mozilla/5.0 (X11; U; Linux; en-US) AppleWebKit/527+ (KHTML, like Gecko, Safari/419.3) Arora/0.6", 22 "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.2pre) Gecko/20070215 K-Ninja/2.1.1", 23 "Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9) Gecko/20080705 Firefox/3.0 Kapiko/3.0", 24 "Mozilla/5.0 (X11; Linux i686; U;) Gecko/20070322 Kazehakase/0.4.5", 25 "Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.0.8) Gecko Fedora/1.9.0.8-1.fc10 Kazehakase/0.5.6", 26 "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.56 Safari/535.11", 27 "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_3) AppleWebKit/535.20 (KHTML, like Gecko) Chrome/19.0.1036.7 Safari/535.20", 28 "Opera/9.80 (Macintosh; Intel Mac OS X 10.6.8; U; fr) Presto/2.9.168 Version/11.52", 29 "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.11 (KHTML, like Gecko) Chrome/20.0.1132.11 TaoBrowser/2.0 Safari/536.11", 30 "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/21.0.1180.71 Safari/537.1 LBBROWSER", 31 "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E; LBBROWSER)", 32 "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; QQDownload 732; .NET4.0C; .NET4.0E; LBBROWSER)", 33 "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.84 Safari/535.11 LBBROWSER", 34 "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.1; WOW64; Trident/5.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E)", 35 "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E; QQBrowser/7.0.3698.400)", 36 "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; QQDownload 732; .NET4.0C; .NET4.0E)", 37 "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; Trident/4.0; SV1; QQDownload 732; .NET4.0C; .NET4.0E; 360SE)", 38 "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; QQDownload 732; .NET4.0C; .NET4.0E)", 39 "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.1; WOW64; Trident/5.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E)", 40 "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/21.0.1180.89 Safari/537.1", 41 "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/21.0.1180.89 Safari/537.1", 42 "Mozilla/5.0 (iPad; U; CPU OS 4_2_1 like Mac OS X; zh-cn) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8C148 Safari/6533.18.5", 43 "Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:2.0b13pre) Gecko/20110307 Firefox/4.0b13pre", 44 "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:16.0) Gecko/20100101 Firefox/16.0", 45 "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.64 Safari/537.11", 46 "Mozilla/5.0 (X11; U; Linux x86_64; zh-CN; rv:1.9.2.10) Gecko/20100922 Ubuntu/10.10 (maverick) Firefox/3.6.10" 47 ] 48 user_agent = random.choice(user_agents) 49 return user_agent 50 51 # 獲取存儲職位信息的json對象,遍歷得到公司名、福利待遇、工做地點、學歷要求、工做類型、發佈時間、職位名稱、薪資、工做年限 52 def get_json(url, datas): 53 user_agent = GetUserAgent() 54 ip_list = [ 55 {"http":"http://138.255.165.86:40600"}, 56 {"http":"http://195.122.185.95:3128"}, 57 {"http":"http://185.203.18.188:3128"}, 58 {"http":"http://103.55.88.52:8080"} 59 ] 60 proxies=random.choice(ip_list) 61 my_headers = { 62 "User-Agent": user_agent, 63 "Referer": "https://www.lagou.com/jobs/list_Python?city=%E5%85%A8%E5%9B%BD&cl=false&fromSearch=true&labelWords=&suginput=", 64 "Content-Type": "application/x-www-form-urlencoded;charset = UTF-8" 65 } 66 time.sleep(5) 67 ses = requests.session() # 獲取session 68 ses.headers.update(my_headers) # 更新 69 ses.proxies.update(proxies) 70 71 cookie_dict = dict() 72 ses.cookies.update(cookie_dict) 73 74 ses.get( 75 "https://www.lagou.com/jobs/list_python?city=%E5%85%A8%E5%9B%BD&cl=false&fromSearch=true&labelWords=&suginput=",headers=my_headers) 76 time.sleep(5) 77 content = ses.post(url=url, data=datas) 78 result = content.json() 79 info = result['content']['positionResult']['result'] 80 info_list = [] 81 for job in info: 82 information = [] 83 information.append(job['positionId']) # 崗位對應ID 84 information.append(job['city']) # 崗位對應城市 85 information.append(job['companyFullName']) # 公司全名 86 information.append(job['companyLabelList']) # 福利待遇 87 information.append(job['district']) # 工做地點 88 information.append(job['education']) # 學歷要求 89 information.append(job['firstType']) # 工做類型 90 information.append(job['formatCreateTime']) # 發佈時間 91 information.append(job['positionName']) # 職位名稱 92 information.append(job['salary']) # 薪資 93 information.append(job['workYear']) # 工做年限 94 info_list.append(information) 95 # 將列表對象進行json格式的編碼轉換,其中indent參數設置縮進值爲2 96 # print(json.dumps(info_list, ensure_ascii=False, indent=2)) 97 # print(info_list) 98 return info_list 99 100 101 def main(): 102 page = int(input('請輸入你要抓取的頁碼總數:')) 103 # kd = input('請輸入你要抓取的職位關鍵字:') 104 # city = input('請輸入你要抓取的城市:') 105 106 info_result = [] 107 title = ['崗位id', '城市', '公司全名', '福利待遇', '工做地點', '學歷要求', '工做類型', '發佈時間', '職位名稱', '薪資', '工做年限'] 108 info_result.append(title) 109 for x in range(56, page + 1): 110 url = 'https://www.lagou.com/jobs/positionAjax.json?needAddtionalResult=false' 111 # 請求參數,pn參數是頁數,kd參數是職位關鍵字 112 datas = { 113 'first': 'false', 114 'pn': x, 115 'kd': 'python', 116 } 117 try: 118 info = get_json(url, datas) 119 info_result = info_result + info 120 print("第%s頁正常採集" % x) 121 except Exception as msg: 122 print("第%s頁出現問題" % x) 123 124 # 建立workbook,即excel 125 workbook = xlwt.Workbook(encoding='utf-8') 126 # 建立表,第二參數用於確認同一個cell單元是否能夠重設值 127 worksheet = workbook.add_sheet('lagoupy', cell_overwrite_ok=True) 128 for i, row in enumerate(info_result): 129 # print(row) 130 for j, col in enumerate(row): 131 # print(col) 132 worksheet.write(i, j, col) 133 workbook.save('lagoupy.xls') 134 135 136 if __name__ == '__main__': 137 main()
數據分析
在執行完上述爬蟲代碼以後,咱們能夠獲得一個lagoupy.xls的文件,裏面存儲的是咱們爬蟲的結果,總共爬取了2640條數據,以下圖所示。
1.數據預處理
因爲咱們爬取下來的數據並非所有都是咱們所要的,或者是有一些數據須要進行加工才能夠用到,這時候數據的預處理就必不可少了。
① 刪除重複值
若是數據中存在重複記錄, 並且重複數量較多時, 勢必會對結果形成影響, 所以咱們應當首先處理重複值。打開lagoupy.xls文件,選中崗位id這一列數據,選擇數據——>刪除重複值,對重複值進行刪除,刪除重複值後,咱們能夠發現,數據從原來的2641條變成2545條。
② 過濾無效數據
因爲某些數據對咱們的數據分析並沒有用處,因此對於這一部分數據咱們能夠不要,在這裏發佈時間是無效數據,因此咱們能夠直接刪除這一列。
③ 加工數據
因爲爬取下來的數據中薪資這一列是相似於15k-30k這樣的數據,而且這樣的數據不能知足咱們的分析需求, 所以須要對薪資這一列數據進行分列操做,把薪資這一列分裂成最低工資和最高工資,接着咱們能夠利用最低工資和最高工資計算出平均工資,並把平均工資做爲新的一列添加進數據表中。
通過上述三個步驟後,咱們最終能夠獲得一個通過數據預處理以後的lagoupy.xls文件,通過預處理以後咱們的數據條數也從原來的2640條變成了2544條,以下圖所示。
2.數據分析
① 學歷要求
根據所統計的數據來看,python對學歷要求以本科和大專居多,其中本科以2071名列第一 。
② 工做類型
咱們把python相關的工做大致分爲八類,分別是產品|需求|項目類、技術類、教育|培訓類、金融類、開發|測試|運維類、生產|加工|製造類、運營|編輯|客服類,其中以開發|測試|運維類這一類工做類型的人才需求多,佔絕對優點。
③ 工做城市
統計各個城市對python相關崗位的需求狀況,由下圖咱們不難發現,北京、上海、深圳、廣州、杭州、成都這六個城市對python這一相關行業的需求比較大。
④ 工做年限
對python相關崗位的工做年限進行統計,咱們能夠發現企業對於python的工做經驗要求以3-5年、1-3年這兩種工做年限需求居多。
⑤ 城市與工資——較發達的城市工資水平較高
由下圖可知,城市與工資有必定的關係,在北上廣深等發達的城市裏,python相關職位的工資較高。
⑥ 學歷與工資——學歷越高工資越高
由圖可知,總體上看學歷越高工資越高。因爲博士學歷只有一條數據,因此這裏可能由於數據不足的緣由致使分析結果有所偏差。
⑦ 工做年限與工資——工做年限越長工資越高
由圖可知,工做年限越長,工資越高。其中由於10年以上只有一條數據,因此對於10年以上的工做經驗所統計出來的數據可能有所誤差。
⑧ 福利待遇
首先,咱們新建一個fuli.txt的文件,把福利待遇這一列粘貼到fuli.txt中並保存,以下圖所示。
其次,咱們對fuli.txt進行詞頻統計,把詞頻統計生成的結果存爲fuli.csv文件。福利待遇詞頻統計代碼以下所示:
1 # -*- coding: utf-8 -*- 2 import jieba # 加載停用表 3 import pandas as pd 4 from wordcloud import WordCloud 5 import matplotlib.pyplot as plt 6 7 # 分解 8 article = open("fuli.txt", "r", encoding='utf-8').read() 9 jieba.add_word('五險一金') 10 jieba.add_word('七險一金') 11 jieba.add_word('六險一金') 12 jieba.add_word('帶薪年假') 13 jieba.add_word('美女多') 14 jieba.add_word('帥哥多') 15 jieba.add_word('年末雙薪') 16 jieba.add_word('績效獎金') 17 jieba.add_word('股票期權') 18 jieba.add_word('扁平管理') 19 jieba.add_word('彈性工做') 20 jieba.add_word('管理規範') 21 jieba.add_word('崗位晉升') 22 jieba.add_word('技能培訓') 23 jieba.add_word('節日禮物') 24 jieba.add_word('帶薪年假') 25 jieba.add_word('按期體檢') 26 jieba.add_word('通信津貼') 27 jieba.add_word('領導好') 28 jieba.add_word('年度旅遊') 29 jieba.add_word('交通補助') 30 jieba.add_word('年終分成') 31 jieba.add_word('豐盛三餐') 32 jieba.add_word('發展空間大') 33 jieba.add_word('午飯補助') 34 jieba.add_word('快速發展') 35 jieba.add_word('發展前景好') 36 jieba.add_word('專項獎金') 37 jieba.add_word('免費班車') 38 jieba.add_word('豐盛三餐') 39 jieba.add_word('科技大牛') 40 words = jieba.cut(article, cut_all=False) # 統計詞頻 41 stayed_line = {} 42 for word in words: 43 if len(word) == 1: 44 continue 45 else: 46 stayed_line[word] = stayed_line.get(word, 0) + 1 47 48 print(stayed_line) # 排序 49 xu = list(stayed_line.items()) 50 # print(xu) 51 52 #存到csv文件中 53 pd.DataFrame(data=xu).to_csv("fuli.csv",encoding="utf_8_sig")
執行完上述代碼後,咱們能夠生成一個fuli.csv文件,以下圖所示。
根據所生成fuli.csv文件使用WordArt對福利待遇生成中文詞雲,結果以下圖所示,咱們能夠發現python相關崗位的福利待遇中,被說起最多的詞彙分別是帶薪年假、股票期權、績效獎金、年末雙薪、節日禮物、技能培訓、按期體檢、五險一金等。