python高级语言设计我是卧底_Python高级应用程序设计任务
一、主題式網絡爬蟲設計方案(15分)
1.主題式網絡爬蟲名稱
基于智聯招聘全國python崗位數據爬蟲
2.主題式網絡爬蟲爬取的內容與數據特征分析
2.1爬取的內容
抓取來源,崗位名稱,薪資,地址,工作經驗,學歷要求,公司名稱,公司行業,公司類型,公司規模,公司福利
2.2數據特征分析
分析python崗位地區熱度,公司共有福利,薪資比例,學歷要求比例
3.主題式網絡爬蟲設計方案概述(包括實現思路與技術難點)
實現思路:
1、通過網頁請求查看網頁格式以及請求過程
2、使用requests庫爬取數據
3、通過xpath語法獲取所要的相關數據
4、使用pyecharts1.2版本進行可視化
技術難點:
城市信息隱藏在網頁中,需要仔細查看才知道,并使用正則匹配出來。頁面數據需要去找對應請求的接口
二、主題頁面的結構特征分析(15分)
1、主題頁面的結構特征
通過瀏覽器的F12鍵打開窗口,然后切換到NetWork下,選擇第一個,然后點response,找到城市數據,頁面崗位信息并沒有在html中查看到,發現是通過異步加載的,通過xhr篩選查看到請求接口
2、HTML頁面解析
1. 城市信息隱藏在網頁中
然后每個城市下的頁數不定,需要動態判斷頁數然后抓取
數據全是異步加載,可以通過network下篩選XHR方式查看到
3、?節點(標簽)查找方法與遍歷發法(必要時畫出節點數結構)
通過正則匹配出城市信息,然后通過正則解析遍歷每個城市,然后通過請求json數據,解析每個崗位的信息,而頁數,則是通過返回json中的numTotal?來判定,因為每頁數據量是90條,而頁數就是條數除以90,如果有余數就加1頁
三、網絡爬蟲程序設計(60分)
爬蟲程序主體要包括以下各部分,要附源代碼及較詳細注釋,并在每部分程序后面提供輸出結果的截圖。
1、數據爬取與采集
爬取網頁中城市信息
1 #構建待抓取url列表
2 defget_province():3 #隨意訪問一個網址
4 start_url = 'https://sou.zhaopin.com/?p=12&jl=489&sf=0&st=0&kw=%E8%BD%AF%E4%BB%B6&kt=3'
5 #發起請求
6 rsp = requests.get(url=start_url, headers=headers)7 #正則匹配城市信息
8 city_str = re.search('__INITIAL_STATE__=(.*?)', rsp.text, re.S).group(1)9 #解析成json格式
10 city_json =json.loads(city_str)11 province = city_json['basic']['dict']['location']['province']12 return province
循環遍歷城市,抓取每個城市下的信息
1 #存放抓取結果
2 page_data =[]3 for item inprovince:4 for sub in item['sublist']:5 #啟動爬蟲
6 result = start_zl(item['name'], sub['code'], keyword)7 if len(result) !=0:8 page_data.extend(result)
每個城市下的抓取代碼,以及獲取頁數翻頁
1 defstart_zl(city_name, city_code, keyword):2 print("抓取城市:" + city_name + "_" + city_code + "信息中")3 page =04 max =None5 result =[]6 whileTrue:7 print('當前{}頁中'.format(page + 1))8 next_page = page * 90
9 now_time = int(time.time() * 1000)10 url = "https://fe-api.zhaopin.com/c/i/sou?"\11 "pageSize=90"\12 "&cityId={}"\13 "&salary=0,0&workExperience=-1&education=-1&companyType=-1&employmentType=-1&jobWelfareTag=-1&"\14 "kw={}"\15 "&start={}"\16 "&kt=3&_v={}"\17 "&x-zp-page-request-id=84cec3861cb34e77a0f76870970d07c1-{}-988542"\18 "&x-zp-client-id=cd61dab4-7d6d-4c58-a963-b9a4c1474d9f".format(city_code, keyword, next_page,19 random.random(), now_time)20 whileTrue:21 try:22 rsp = requests.get(url=url, headers=headers)23 desc_json =json.loads(rsp.text)24 if desc_json['data']['numTotal'] ==0:25 max =026 break
27 #獲取頁數
28 if max isNone:29 count = desc_json['data']['numTotal']30 if count <= 90:31 max = 1
32 else:33 if count % 90 ==0:34 max = count // 90
35 else:36 max = count // 90 + 1
37 for item in desc_json['data']['results']:38 try:39 result.append(40 ['zhilian', item['jobName'], item['salary'], city_name, item['workingExp']['name'], item['eduLevel']['name'], item['company']['name'],41 item['jobType']['items'][0]['name'], item['company']['type']['name'],42 item['company']['size']['name'], '_'.join(item['welfare'])])43 exceptException as e:44 continue
45 break
46 exceptException as e:47 print(url)48 print("錯誤:", e, ", 返回結果:", rsp.text)49 if page >=max:50 break
51 page += 1
52
53 return result
2、對數據進行清洗和處理
通過pandas讀取csv文件
1 #讀取excel文件
2 df = pd.read_csv('最終數據.csv', encoding='utf-8')
對學歷信息進行處理,合并中專、中技到中專/中技,將不明數據合并到其他中
1 #格式化學歷信息
2 education =[]3 for c in df['學歷要求']:4 if '月' inc:5 c = '其他'
6 elif c == '中專' or c == '中技':7 c = '中專/中技'
8 education.append(c)9 df['education'] =education10 #按樓層分組
11 df_education = df.groupby(df['education'])12 df_education =df_education.size()13 value =df_education.values14 attr = list(df_education.keys())
對薪資數據進行處理,首先去掉面議等數據,然后針對薪資,抓取格式是2-10k這種,我們正則匹配出數字,兩位的就取兩位數字和,然后除2,即中位值
1 pattern = '\d+'
2 #去除 "薪資面議" 等無效數據
3 df.drop(df[df['薪資'].str.contains('面議')].index, inplace=True)4
5 salary_list = df['薪資'].values6 #將字符串轉化為列表
7 df['salary'] = df['薪資'].str.findall(pattern)8 avg_salary =[]9 #統計平均工資
10 for salary insalary_list:11 k =re.findall(pattern, salary)12 int_list = [int(n) for n ink]13 #取工資區間平均值
14 if len(int_list) == 2:15 avg_wage = (int_list[1] + int_list[0]) / 2
16 else:17 avg_wage =int_list[0]18 #去除無效數據
19 if 0 < avg_wage < 100:20 avg_salary.append(avg_wage * 1000)
3、文本分析
針對公司福利采用了jieba分詞,并進行詞云圖展示
1 #公司福利詞云圖
2 defword_cloud():3 wc = WordCloud({"theme": ThemeType.MACARONS})4 word_dict ={}5 for word in df['公司福利']:6 if 'nan' instr(word):7 continue
8 r = r"[0-9\s+\.\!\/_,$%^*()?;;:-【】+\"\']+|[+——!,;:。?、~@#¥%……&*()]+"
9 #去除特殊符號
10 word = re.sub(r, '', str(word), re.S)11 #cut分詞,并去重
12 words = set(jieba.cut(word, cut_all=False))13 #統計詞頻
14 for word inwords:15 if len(word) < 2:16 continue
17 if word not inword_dict:18 word_dict[word] = 1
19 else:20 word_dict[word] += 1
21 #詞頻排序
22 word_list = sorted(word_dict.items(), key=lambda x: x[1], reverse=True)23 #生成圖
24 wc.add("", word_list, word_size_range=[20, 100], shape=SymbolType.DIAMOND)25 wc.set_global_opts(title_opts=opts.TitleOpts(title="福利分析"))26 return wc
4、可視化處理
學歷崗位占比圖
1 left_num = 10
2 rigth_num = 30
3 for x inrange(0, len(value)):4 pie.add(5 "",6 [[attr[x], round(value[x] / val_sum * 100, 2)], ["剩余", round((val_sum - value[x]) / val_sum * 100, 2)]],7 center=[str(left_num) + '%', str(rigth_num) + '%'],8 radius=[60, 80],9 label_opts=new_label_opts()10 )11 left_num += 20
12 if left_num > 90:13 left_num = 10
14 rigth_num += 40
15 pie.set_global_opts(16 title_opts=opts.TitleOpts(title="學歷崗位數對比"),17 legend_opts=opts.LegendOpts(18 type_="scroll", pos_top="5%"
19 ),20 )
城市地圖崗位對應圖
1 map = Map({"theme": ThemeType.MACARONS})2 map.add(3 "崗位數",4 [list(z) for z inzip(attr, value)],5 "china"
6 )7 map.set_global_opts(8 title_opts=opts.TitleOpts(title="地區崗位數對比"),9 visualmap_opts=opts.VisualMapOpts(max_=200),10 )
工資區間柱狀圖
1 label =[2 '3k以下', '3k-5k', '5k-8k', '8k-12k', '12k-15k', '15k-20k', '20k-25k', '25k以上'
3 ]4 bar =Bar()5 bar.add_xaxis(label)6 bar.add_yaxis('智聯', pin_value)7
8 bar.set_global_opts(title_opts=opts.TitleOpts(title="平臺崗位工資對比"))
5、數據持久化
采用csv方式儲存
1 with open("智聯全國數據.csv", "w", newline='', encoding='utf-8') as datacsv:2 #dialect為打開csv文件的方式,默認是excel,delimiter="\t"參數指寫入的時候的分隔符
3 csvwriter = csv.writer(datacsv, dialect=("excel"))4 #csv文件插入一行數據
5 csvwriter.writerow(['抓取來源', '崗位名稱', '薪資', '工作地點', '工作經驗', '學歷要求', '公司名稱', '公司行業', '公司類型', '公司規模', '公司福利'])6 for temp inpage_data:7 #csv文件插入一行數據
8 csvwriter.writerow(temp)
6、最終代碼
1 importrequests2 importtime3 importjson4 importcsv5 importre6 importrandom7 importopenpyxl8
9
10 defstart_zl(city_name, city_code, keyword):11 print("抓取城市:" + city_name + "_" + city_code + "信息中")12 page =013 max =None14 result =[]15 whileTrue:16 print('當前{}頁中'.format(page + 1))17 next_page = page * 90
18 now_time = int(time.time() * 1000)19 url = "https://fe-api.zhaopin.com/c/i/sou?"\20 "pageSize=90"\21 "&cityId={}"\22 "&salary=0,0&workExperience=-1&education=-1&companyType=-1&employmentType=-1&jobWelfareTag=-1&"\23 "kw={}"\24 "&start={}"\25 "&kt=3&_v={}"\26 "&x-zp-page-request-id=84cec3861cb34e77a0f76870970d07c1-{}-988542"\27 "&x-zp-client-id=cd61dab4-7d6d-4c58-a963-b9a4c1474d9f".format(city_code, keyword, next_page,28 random.random(), now_time)29 whileTrue:30 try:31 rsp = requests.get(url=url, headers=headers)32 desc_json =json.loads(rsp.text)33 if desc_json['data']['numTotal'] ==0:34 max =035 break
36 #獲取頁數
37 if max isNone:38 count = desc_json['data']['numTotal']39 if count <= 90:40 max = 1
41 else:42 if count % 90 ==0:43 max = count // 90
44 else:45 max = count // 90 + 1
46 for item in desc_json['data']['results']:47 try:48 result.append(49 ['zhilian', item['jobName'], item['salary'], city_name,50 item['workingExp']['name'], item['eduLevel']['name'], item['company']['name'],51 item['jobType']['items'][0]['name'], item['company']['type']['name'],52 item['company']['size']['name'], '_'.join(item['welfare'])])53 exceptException as e:54 continue
55 break
56 exceptException as e:57 print(url)58 print("錯誤:", e, ", 返回結果:", rsp.text)59 if page >=max:60 break
61 page += 1
62
63 returnresult64
65
66 #構建待抓取url列表
67 defget_province():68 #隨意訪問一個網址
69 start_url = 'https://sou.zhaopin.com/?p=12&jl=489&sf=0&st=0&kw=%E8%BD%AF%E4%BB%B6&kt=3'
70 #發起請求
71 rsp = requests.get(url=start_url, headers=headers)72 #正則匹配城市信息
73 city_str = re.search('__INITIAL_STATE__=(.*?)', rsp.text, re.S).group(1)74 #解析成json格式
75 city_json =json.loads(city_str)76 province = city_json['basic']['dict']['location']['province']77 returnprovince78
79
80 if __name__ == "__main__":81 headers ={82 "User-Agent": 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36'
83 }84 #獲取城市信息
85 province =get_province()86 print(province)87 #搜索關鍵詞
88 keyword = 'python'
89
90 #存放抓取結果
91 page_data =[]92 for item inprovince:93 for sub in item['sublist']:94 #啟動爬蟲
95 result = start_zl(item['name'], sub['code'], keyword)96 if len(result) !=0:97 page_data.extend(result)98
99 with open("智聯全國數據.csv", "w", newline='', encoding='utf-8') as datacsv:100 #dialect為打開csv文件的方式,默認是excel
101 csvwriter = csv.writer(datacsv, dialect=("excel"))102 #csv文件插入一行數據
103 csvwriter.writerow(['抓取來源', '崗位名稱', '薪資', '工作地點', '工作經驗', '學歷要求', '公司名稱', '公司行業', '公司類型', '公司規模', '公司福利'])104 for temp inpage_data:105 #csv文件插入一行數據
106 csvwriter.writerow(temp)107
108 print("抓取完成")
1 from pyecharts.charts importPage, Bar, Map, WordCloud, Pie, Line2 from pyecharts importoptions as opts3 importpandas as pd4 from pyecharts.commons.utils importJsCode5 from pyecharts.globals importThemeType, SymbolType6 importre7 importjieba8
9
10 #學歷分布餅圖
11 defpie_multiple():12 #格式化學歷信息
13 education =[]14 for c in df['學歷要求']:15 if '月' inc:16 c = '其他'
17 elif c == '中專' or c == '中技':18 c = '中專/中技'
19 education.append(c)20 df['education'] =education21 #按樓層分組
22 df_education = df.groupby(df['education'])23 df_education =df_education.size()24
25 value =df_education.values26 attr =list(df_education.keys())27 print(attr)28 val_sum =sum(value)29 pie = Pie({"theme": ThemeType.MACARONS})30 #格式化顯示格式
31 fn = """
32 function(params) {33 if(params.name == '剩余')34 return '\\n\\n\\n' + params.name + ' : ' + params.value + '%';35 return params.name + ' : ' + params.value + '%';36 }37 """
38
39 defnew_label_opts():40 return opts.LabelOpts(formatter=JsCode(fn), position="center")41
42 left_num = 10
43 rigth_num = 30
44 for x inrange(0, len(value)):45 pie.add(46 "",47 [[attr[x], round(value[x] / val_sum * 100, 2)], ["剩余", round((val_sum - value[x]) / val_sum * 100, 2)]],48 center=[str(left_num) + '%', str(rigth_num) + '%'],49 radius=[60, 80],50 label_opts=new_label_opts()51 )52 left_num += 20
53 if left_num > 90:54 left_num = 10
55 rigth_num += 40
56 pie.set_global_opts(57 title_opts=opts.TitleOpts(title="學歷崗位數對比"),58 legend_opts=opts.LegendOpts(59 type_="scroll", pos_top="5%"
60 ),61 )62 returnpie63
64
65 #崗位覆蓋地區圖
66 defmap_visualmap():67 #格式化地區信息
68 county =[]69 for cou in df['工作地點']:70 cou = cou[:2]71 county.append(cou)72 df['county'] =county73 #按樓層分組
74 df_county = df.groupby(df['county'])75 #獲取分組后的數據
76 county_size =df_county.size()77 value =county_size.values78 value = [int(val) for val invalue]79 attr =list(county_size.keys())80
81 map = Map({"theme": ThemeType.MACARONS})82 map.add(83 "崗位數",84 [list(z) for z inzip(attr, value)],85 "china"
86 )87 map.set_global_opts(88 title_opts=opts.TitleOpts(title="地區崗位數對比"),89 visualmap_opts=opts.VisualMapOpts(max_=200),90 )91 returnmap92
93
94 #工資區間柱狀圖
95 defbar_img():96 fanwei = [0, 3000, 5000, 8000, 12000, 15000, 20000, 25000, 100000]97 label =[98 '3k以下', '3k-5k', '5k-8k', '8k-12k', '12k-15k', '15k-20k', '20k-25k', '25k以上'
99 ]100 bar =Bar()101 bar.add_xaxis(label)102
103 pattern = '\d+'
104 #去除 "薪資面議" 等無效數據
105 df.drop(df[df['薪資'].str.contains('面議')].index, inplace=True)106
107 salary_list = df['薪資'].values108 #將字符串轉化為列表
109 df['salary'] = df['薪資'].str.findall(pattern)110 avg_salary =[]111 #統計平均工資
112 for salary insalary_list:113 k =re.findall(pattern, salary)114 int_list = [int(n) for n ink]115 #取工資區間平均值
116 if len(int_list) == 2:117 avg_wage = (int_list[1] + int_list[0]) / 2
118 else:119 avg_wage =int_list[0]120 #去除無效數據
121 if 0 < avg_wage < 100:122 avg_salary.append(avg_wage * 1000)123
124 df_avg = pd.DataFrame({'avg': avg_salary})125 #對工資進行分組 比如:0-3000, 3000-5000這種
126 fenzu = pd.cut(df_avg['avg'].values, fanwei, right=False) #分組區間
127 pin_shu = fenzu.value_counts() #series,區間-個數
128 pin_value =pin_shu.values129 pin_value = [int(pin) for pin inpin_value]130
131 bar.add_yaxis('智聯', pin_value)132
133 bar.set_global_opts(title_opts=opts.TitleOpts(title="平臺崗位工資對比"))134 returnbar135
136
137 #公司福利詞云圖
138 defword_cloud():139 wc = WordCloud({"theme": ThemeType.MACARONS})140 word_dict ={}141 for word in df['公司福利']:142 if 'nan' instr(word):143 continue
144 r = r"[0-9\s+\.\!\/_,$%^*()?;;:-【】+\"\']+|[+——!,;:。?、~@#¥%……&*()]+"
145 #去除特殊符號
146 word = re.sub(r, '', str(word), re.S)147 #cut分詞,并去重
148 words = set(jieba.cut(word, cut_all=False))149 #統計詞頻
150 for word inwords:151 if len(word) < 2:152 continue
153 if word not inword_dict:154 word_dict[word] = 1
155 else:156 word_dict[word] += 1
157 #詞頻排序
158 word_list = sorted(word_dict.items(), key=lambda x: x[1], reverse=True)159 #生成圖
160 wc.add("", word_list, word_size_range=[20, 100], shape=SymbolType.DIAMOND)161 wc.set_global_opts(title_opts=opts.TitleOpts(title="福利分析"))162 returnwc163
164
165 if __name__ == "__main__":166 #讀取excel文件
167 df = pd.read_csv('智聯全國數據.csv', encoding='utf-8')168
169 #自定義畫布,多圖合一
170 page = Page(layout=Page.SimplePageLayout)171
172 #添加到頁面
173 page.add(pie_multiple(), map_visualmap(), bar_img(), word_cloud())174 #page.add()
175
176 page.render('智聯可視化.html')
四、結論(10分)
1、經過對主題數據的分析與可視化,可以得到哪些結論?
1、python崗位,果然還是大城市就業好,北上廣相對其他地區,明顯好就業些
2、雖然說研究生以上文憑要好很多,但是針對學歷這塊,本科文憑還是很吃香,主要集中是在這一塊
3、通過工資圖發現,一般python崗位的工資集中在5k-20k間,其中8k-12k的崗位數最多
4、而公司福利方面,基本每家公司都有五險一金這些基本福利,還是不錯的
2、對本次程序設計任務完成的情況做一個簡單的小結
通過這次的爬蟲作業,正好也想看下關于python的就業情況,也算有了個了解,針對代碼方面,還是有很多沒明白的,但是也學習到了很多知識,以后會繼續加油。
總結
以上是生活随笔為你收集整理的python高级语言设计我是卧底_Python高级应用程序设计任务的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 查询成绩最好的前两名_收藏转发!一线老师
- 下一篇: pandas describe函数_SQ