1. 程式人生 > 其它 >爬取實習吧與python相關的招聘資訊及資料視覺化(含程式碼)

爬取實習吧與python相關的招聘資訊及資料視覺化(含程式碼)

目錄
資料爬取
資料處理
讀取檔案
刪除無意義列
刪除重複的值
資料視覺化
工資資訊視覺化
城市資訊視覺化
實習時間資訊視覺化
Jieba分詞對職位描述視覺化

本文就實習吧招聘網站上截止到2020年12月31號有關於python相關的招聘資訊共109條做出l一個簡單的爬取和資料分析,尚有很多不足。如有任何錯誤或紕漏,歡迎指出討論。
資料爬取
將實習吧刺蝟實習裡面有關python職位的招聘資訊爬取出來,儲存在一個CSV檔案中。檢視招聘網站可以發現,一共有109條資料,其中包含已下架的招聘資訊。雖然這部分下架的招聘資訊看起來是毫無意義,但其實也能通過其中獲取到很多有用的資訊。

爬取後的是儲存在CSV檔案中,檔案部分內容如下圖所示,爬取的內容主要包含了工作名稱、公司名稱、公司所在城市、招聘需求學歷、實習工資、實習時間、職位描述、公司其他職位以及公司的一下說明:

在這裡插入圖片描述
就這些資料我們就可以對其進行分析視覺化,獲得資料背後隱藏的祕密

資料爬取部分的程式碼如下所示:

import requests
from bs4 import BeautifulSoup
import os.path
import json
import os
import csv

import io
import sys

import jieba
import wordcloud

import traceback
import cgitb

#要加上這一句和import 否則後續一直會報’gbk’的錯誤
sys.stdout=io.TextIOWrapper(sys.stdout.buffer,encoding=‘utf-8’)#‘gb18030’

class shixi():

#發爬蟲機制,加Headers,異常處理URLError類,用try-except語句來包圍並捕獲相應的異常
def get_html(self,url):
	try:
		headers = {'user-agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.117 Safari/537.36'}#偽裝爬蟲
		resp = requests.get(url, headers = headers)
		return resp.text
	except:
		print ('url is wrong') #異常後輸出語句
		

#將爬取資訊存入CSV操作
def dict2cvs(self,dic,filename):

	file_exists=os.path.isfile(filename)
	#a訪問方式為追加,newline=''是為了防止寫入的檔案總有空行的問題
	with open(filename,'a',encoding='utf-8',newline='') as f: 
		
		headers=dic.keys()
		w =csv.DictWriter(f,delimiter=',', lineterminator='\n', fieldnames=headers)
		
		if not file_exists :
			w.writeheader()

		#writerow()逐行寫入,writerrow()是多行寫入
		w.writerow(dic)
	print('當前行寫入csv成功!')	

#爬取職位資訊頁面
def draw_base_list(self,url):
	html = self.get_html(url)

	##json.loads 實現json字串轉化為python的資料型別
	data = json.loads(html)
	try:
	#json的語法 "[]"迭代器標示(可以在裡邊做簡單的迭代操作,如陣列下標,根據內容選值等)這樣就將lists選擇出來
		news = data['data']['lists']
		for n in news:

			jobid=n['jobid']
			#二級頁面的URL,這個網址就用來爬取職位描述,因為這一部分是靜態的
			url2='https://www.ciwei.net/internship/job/'+str(jobid)

			#這個網址是用來爬其他職位的網址,這是一個動態的,所以雖然和上面都在一個網頁,但是網址不一樣
			company_id=n['company_id']
			url3='https://www.ciwei.net/api/Shixi_V2_Job/getJobByCid?page=1&pageSize=10&company_id='+str(company_id)

			title = n['title']    
			comfullname = n['comfullname'] 
			comname = n['comname']
			cityName = n['cityName']
			education = n['education']  
			salary = n['salary']  
			fulltime_type_string = n['fulltime_type_string'] 
			label= n['label']
			dat2={
				'city':cityName
			}
			self.dict2cvs(dat2,'城市資訊.csv')
			self.draw_detail_list(url2,url3,jobid,title,comname,cityName,education,salary,fulltime_type_string,label)	
	except Exception as e:
	# except Exception,e:#這樣會報錯,SyntaxError: invalid syntax,因為except Exception, e: 這個語法需要用python2版本去執行,我們使用的是python3。所以要換成except Exception as e:
		print(repr(e))
		print('draw_base_list is wrong')
	pass


#爬取二級詳情頁
def draw_detail_list(self,url,url1,jobid,title,comname,cityName,education,salary,fulltime_type_string,label):
# def draw_detail_list(self,url):
	#職位描述部分
	html = self.get_html(url)
	soup=BeautifulSoup(html,'lxml')
	#爬取職位描述的部分
	try:
		lilist=soup.find('ul',{'class':'job-desc___3cBCa'})
		l=lilist.find_all('span')
		l2=lilist.find_all('h5')#是ResultSet型別不能寫'.text'# print(type(l[0]))可迭代 型別Tag 就可以寫'.text'
		s=''
		s4=''
		for i in range(len(lilist)):
			s=l2[i].text.strip()+l[i].text.strip()+'\n'+'\n'
			s4=s4+s
		#爬取其他職位部分,因為是動態網頁,所以要重新用json解析一下
		html1 = self.get_html(url1)
		data1 = json.loads(html1)
		news1 = data1['data']['jobList']
		t=''
		for n in news1:
			tit=n['title']+'\n'
			t=tit+t
		print(t)
		dat={
			'jobid':jobid,
			'工作名稱':title,
			'公司名稱':comname,
			'城市':cityName,
			'要求學歷':education,
			'工資':salary,
			'實習時間':fulltime_type_string,
			'職位描述':s4,
			'其他職位':t,
			'說明':label
			}
		dat1={
			'職位描述':s4,
		}
		#將資訊存入CSV檔案
		self.dict2cvs(dat1,'職位描述.csv')
		self.dict2cvs(dat,'所有資訊.csv')

	#捕捉異常並輸出錯誤資訊
	except Exception as e:
		print(repr(e))
		print('draw_detail_list is wrong')
	pass

s=shixi()
if name == ‘main’:
print(‘爬取實習吧’)
for page in range(1,12):
url=‘https://www.ciwei.net/api/Shixi_Pc/search?city=0&getCount=1&key=Python&s_c=1&page=’+str(page)+’&source=pc’
print(url)
s.draw_base_list(url)
pass

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
資料處理
爬取後儲存在CSV檔案中的樣式就是如最上面那個圖一樣,然後我們就對這些資料來進行處理,因為不是所有的資料都是有用的,我們可以選擇性的對資料先處理一遍,使之成為我們需要的東西,在對資料進行視覺化分析

對資料處理使用的是jupyter notebook。

讀取檔案
import pandas as pd
import random
import ipywidgets as widegts
data=pd.read_csv(r’C:\Users\DELL\Desktop\Python\答辯\所有資訊.csv’,encoding=‘utf8’)
data
1
2
3
4
5
刪除無意義列
檔案儲存裡的jobid列是網頁獲取時的一個關鍵id,根據jobid我們就可以構造網頁從而進行後續的爬取,但是對於我們現在的有關招聘資訊的資料分析來說是沒有意義的,所以我們就將其刪除掉。對於其他職位來列來說也是,因為我們是分析跟python有關的這些招聘資訊,所以對於這個公司還招聘的其他職位我們目前不做分析,也就將這一行刪除掉

刪除使用的是drop()方法;最後就留下了工作名稱、公司名稱、城市、要求學歷、工資、實習時間、職位描述、說明這幾列資料

#刪除jobid和其他職位列
data=data.drop(columns=[“jobid”,“其他職位”])#這兩種都是刪除列的方法
data
1
2
3
刪除重複的值
因為有些公司可能釋出重複的招聘資訊,所以將職位名稱和公司名稱相同的招聘資訊刪除掉

運用data.duplicated(subset=[])方法,首先查詢一共有多少個重複的行,得到的結果是有19行是重複的資料

#檢查是否有重複的行
duplicated_data=data.duplicated(subset=[‘工作名稱’,‘公司名稱’])
data=data[duplicated_data]
len(data)

#19
1
2
3
4
5
6
然後就將重複的行刪除掉,一共有109行把重複的19行刪除掉那麼就剩下90行資料

刪除掉重複的行,只保留最開始出現的

data.drop_duplicates(subset=[‘工作名稱’,‘公司名稱’], keep=‘first’, inplace=True)
data
len(data)

#90
1
2
3
4
5
6
資料視覺化
工資資訊視覺化
對於工資,各個公司提供的工資表示範圍不完全不同,有些是以天為單位,有些是以月為單位,有些是面議,故不能直接比較大小判斷工資水平,所以我選擇了餅圖來展示,對所有出現了的工資情況總體畫一個餅圖,根據工資的佔比情況來分析各個公司的招聘工資情況

首先是將所有的工資情況和每個工資出現了多少次計算出來生成data2

data1=data.drop_duplicates(subset=[‘工資’])
data2=pd.DataFrame(data1[‘工資’],columns=[‘工資’])
data2[‘工資數’]=[len(data[data[‘工資’]‘200-300元/天’]),len(data[data[‘工資’]‘120-180元/天’]),
len(data[data[‘工資’]‘150-200元/天’]),len(data[data[‘工資’]‘150-300元/天’]),
len(data[data[‘工資’]‘面議’]),len(data[data[‘工資’]‘300-500元/天’]),
len(data[data[‘工資’]‘100-180元/天’]),len(data[data[‘工資’]‘100-150元/天’]),
len(data[data[‘工資’]‘1-2K/月’]),len(data[data[‘工資’]‘2-4K/月’]),
len(data[data[‘工資’]‘4-6K/月’]),len(data[data[‘工資’]‘60-100元/天’])]
data2
1
2
3
4
5
6
7
8
9
在這裡插入圖片描述
一共有12種薪資情況,再根據次數畫出餅圖如下:

import numpy as np
import matplotlib.pyplot as plt
import matplotlib

#解決漢字亂碼問題
matplotlib.rcParams[‘font.sans-serif’]=[‘SimHei’] #使用指定的漢字字型型別(此處為黑體)

plt.figure(figsize=(6,6))
label=data2[‘工資’].values.tolist()
explode=[0.01,0.01,0.01,0.01,0.01,0.01,0.01,0.01,0.01,0.01,0.01,0.01]

plt.pie(x=data2[‘工資數’].values.tolist(),explode=explode,labels=label,autopct=’%1.1f%%’)
plt.title(‘工資分佈情況’)
plt.savefig(‘餅圖.png’)
plt.show()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
在這裡插入圖片描述
注意一點如果在圖中是有漢字的話,要對編碼進行處理,否則漢字是顯示不出來的,例如matplotlib.rcParams[‘font.sans-serif’]=[‘SimHei’]這個就是將指定漢字為黑體

150-200元/天換算過來即為4500-6000/月,所以可以看出工資佔比4-6K/月是佔比最多的,剩下200-300元/天即6-9K/月
的工資也比其他佔比大一些,由圖也可以看出面議的佔比也不算少數,所以也會有較多公司選擇面議的方式來決定工資,
也就是取決於個人的水平了
1
2
3
城市資訊視覺化
一樣的先統計所有招聘資訊出現的城市,並且統計次數

data1=data.drop_duplicates(subset=[‘城市’])
data2=pd.DataFrame(data1[‘城市’],columns=[‘城市’])
data2[‘城市數’]=[len(data[data[‘城市’]‘上海’]),len(data[data[‘城市’]‘深圳’]),len(data[data[‘城市’]‘杭州’]),len(data[data[‘城市’]‘北京’]),
len(data[data[‘城市’]‘廣州’]),len(data[data[‘城市’]‘無錫’]),len(data[data[‘城市’]‘廈門’]),len(data[data[‘城市’]‘武漢’]),
len(data[data[‘城市’]‘南京’]),len(data[data[‘城市’]‘瀋陽’]),len(data[data[‘城市’]‘長沙’]),len(data[data[‘城市’]‘大連’]),
len(data[data[‘城市’]‘西安’]),len(data[data[‘城市’]‘成都’])]

data2
1
2
3
4
5
6
7
8
得到的結果:
在這裡插入圖片描述
將這些情況畫成柱狀圖

plt.rcParams[‘figure.figsize’]=[13,8]#這是這個表的大小

lable=data2[‘城市’].values.tolist()#刻度標籤
plt.bar(range(14),data2[‘城市數’].values.tolist(),width=0.5)#14根柱子,對應值,寬度

#下面兩個是x軸,y軸的表是的是啥
plt.ylabel(‘城市數’,fontsize=15)
plt.xlabel(“城市”,fontsize=15)

#每一個柱子代表的城市
plt.xticks(range(14),lable)
plt.title(‘招聘城市情況’)
plt.show()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
在這裡插入圖片描述

清楚的可以看到對於python相關職業的招聘,北上廣這樣的大城市是更多的。尤其是北京,所以如果想找
有關與python方面的工作的話,北上廣是不錯的選擇

1
2
同時對與城市資訊也可用詞雲圖來分析,在爬取的時候就順便將城市資訊單獨儲存了一個CSV檔案,所以直接讀取檔案生成詞雲即可

f=open(‘C:/Users/DELL/Desktop/Python/答辯/城市資訊.csv’,encoding=‘utf-8’)
t=f.read()
f.close()
l=jieba.lcut(t)
string=’ '.join(l)
w=wordcloud.WordCloud(background_color=‘white’,font_path=‘C:/Windows/Fonts/STKAITI.TTF’,width=1000,height=900,)#font_path是字型,
w.generate(string)#向wordcloud物件w中載入文字txt
w.to_file(r"城市.png")#將詞雲輸出為影象檔案
1
2
3
4
5
6
7
8
圖片生成如下
在這裡插入圖片描述

由詞雲圖片上大大的北上廣三個城市也可以明顯看出北上廣對於python方面的招聘會更多

1
實習時間資訊視覺化
先對實習時間總體做一個統計,得到這樣一個結果
在這裡插入圖片描述
然後將其畫成餅圖

plt.figure(figsize=(6,6))
label=data2[‘實習時間’].values.tolist()
explode=[0.01,0.01,0.01]

plt.pie(x=data2[‘實習時間數’].values.tolist(),explode=explode,labels=label,autopct=’%1.1f%%’)
plt.title(‘實習時間分佈情況’)

plt.show()
1
2
3
4
5
6
7
8
結果如下
在這裡插入圖片描述

由圖我們可以看出,對於所有的招聘,實習時間都是要求至少3或4或5天,對於要求至少4天、5天的公司佔多數

1
Jieba分詞對職位描述視覺化
首先我們來對Jieba做一個簡單的介紹
(1) jieba庫概述:jieba是優秀的中文分詞第三方庫

中文文字需要通過分詞獲得單個的詞語
jieba是優秀的中文分詞第三方庫,需要額外安裝
jieba庫提供三種分詞模式,最簡單隻需掌握一個函式
(2) jieba分詞的原理: Jieba分詞依靠中文詞庫

利用一箇中文詞庫,確定漢字之間的關聯概率
漢字間概率大的組成片語,形成分詞結果
除了分詞,使用者還可以新增自定義的片語
(3) jieba分詞的三種模式:精確模式、全模式、搜尋引擎模式

精確模式:把文字精確的切分開,不存在冗餘單詞
全模式:把文字中所有可能的詞語都掃描出來,有冗餘
搜尋引擎模式:在精確模式基礎上,對長詞再次切
(4) jieba庫常用函式
在這裡插入圖片描述