用python爬取前程無(wú)憂網(wǎng),看看我們是否真的“前程無(wú)憂”?
The best time to plant a tree was 10 years ago,the second best time is now.
種一棵樹(shù)最好的時(shí)間是十年前,其次是現(xiàn)在。
利用python爬取在前程無(wú)憂網(wǎng)搜索python關(guān)鍵字出現(xiàn)的最新的招聘數(shù)據(jù),保存到本地Excel,進(jìn)行數(shù)據(jù)查看和預(yù)處理,然后利用matplotlib進(jìn)行數(shù)據(jù)分析和可視化。
1. 爬取數(shù)據(jù)
目標(biāo)url:https://www.51job.com/
在前程無(wú)憂網(wǎng)輸入關(guān)鍵字python,搜索有關(guān)的崗位數(shù)據(jù)。翻頁(yè)查看這些招聘崗位信息,可以發(fā)現(xiàn)url翻頁(yè)的規(guī)律。
檢查網(wǎng)頁(yè)源代碼,可以找到想要提取的數(shù)據(jù)。

部分爬蟲(chóng)代碼如下,完整見(jiàn)文末下載
????async?def?parse(self,?text):
????????#?正則匹配提取數(shù)據(jù)
????????try:
????????????job_name?=?re.findall('"job_name":"(.*?)",',?text)??????????#?職位
????????????company_name?=?re.findall('"company_name":"(.*?)",',?text)??#?公司名稱
????????????salary?=?re.findall('"providesalary_text":"(.*?)",',?text)
????????????salary?=?[i.replace('\\',?'')?for?i?in?salary]??????????????#?薪酬?????去掉?\?符號(hào)
????????????city?=?re.findall('"workarea_text":"(.*?)",',?text)?????????#?城市
????????????job_welfare?=?re.findall('"jobwelf":"(.*?)",',?text)????????#?職位福利
????????????attribute_text?=?re.findall('"attribute_text":(.*?),"companysize_text"',?text)
????????????attribute_text?=?['|'.join(eval(i))?for?i?in?attribute_text]
????????????companysize?=?re.findall('"companysize_text":"(.*?)",',?text)??#?公司規(guī)模
????????????category?=?re.findall('"companyind_text":"(.*?)",',?text)
????????????category?=?[i.replace('\\',?'')?for?i?in?category]?????????????#?公司所屬行業(yè)??去掉?\?符號(hào)
????????????datas?=?pd.DataFrame({'company_name':?company_name,?'job_name':?job_name,?'companysize':?companysize,?'city':?city,?'salary':?salary,?'attribute_text':?attribute_text,?'category':?category,?'job_welfare':?job_welfare})
????????????datas.to_csv('job_info.csv',?mode='a+',?index=False,?header=True)
????????????logging.info({'company_name':?company_name,?'job_name':?job_name,?'company_size':?companysize,?'city':?city,?'salary':?salary,?'attribute_text':?attribute_text,?'category':?category,?'job_welfare':?job_welfare})
????????except?Exception?as?e:
????????????print(e)
運(yùn)行效果如下:


爬取了200頁(yè)的招聘數(shù)據(jù),共10000條招聘信息,用時(shí)49.919s。
2. 數(shù)據(jù)查看和預(yù)處理
import?pandas?as?pd
df?=?pd.read_csv('job_info.csv')
#?異步爬蟲(chóng)爬取數(shù)據(jù)時(shí)??datas.to_csv('job_info.csv',?mode='a+',?index=False,?header=True)??刪除多的列名
df1?=?df[df['salary']?!=?'salary']
#?查看前10行
df1.head(10)

#?city那一列數(shù)據(jù)??處理為城市
#?按?-?分割???expand=True??0那一列重新賦值給df['city']
df1['city']?=?df1['city'].str.split('-',?expand=True)[0]
df1.head(10)

#?經(jīng)驗(yàn)要求??學(xué)歷要求???有的話是在attribute_text列里
df['attribute_text'].str.split('|',?expand=True)

df1['experience']?=?df1['attribute_text'].str.split('|',?expand=True)[1]
df1['education']?=?df1['attribute_text'].str.split('|',?expand=True)[2]
df1

保存為已清洗數(shù)據(jù)
df1.to_csv('已清洗數(shù)據(jù).csv',?index=False)
查看索引、數(shù)據(jù)類型和內(nèi)存信息
df2?=?pd.read_csv('已清洗數(shù)據(jù).csv')
df2.info()

3. 數(shù)據(jù)分析與可視化
(1) 柱形圖展示招聘崗位數(shù)最多的城市Top10
代碼如下:
import?pandas?as?pd
import?random
import?matplotlib.pyplot?as?plt
import?matplotlib?as?mpl
df?=?pd.read_csv('已清洗數(shù)據(jù).csv')
#?有些是異地招聘???過(guò)濾掉
data?=?df[df['city']?!=?'異地招聘']['city'].value_counts()
city?=?list(data.index)[:10]????#?城市
nums?=?list(data.values)[:10]???#?崗位數(shù)
print(city)
print(nums)
colors?=?['#FF0000',?'#0000CD',?'#00BFFF',?'#008000',?'#FF1493',?'#FFD700',?'#FF4500',?'#00FA9A',?'#191970',?'#9932CC']
random.shuffle(colors)
#?設(shè)置大小???像素
plt.figure(figsize=(9,?6),?dpi=100)
#?設(shè)置中文顯示
mpl.rcParams['font.family']?=?'SimHei'
#?繪制柱形圖??設(shè)置柱條的寬度和顏色
#?color參數(shù)??每根柱條配置不同顏色
plt.bar(city,?nums,?width=0.5,?color=colors)
#?添加描述信息
plt.title('招聘崗位數(shù)最多的城市Top10',?fontsize=16)
plt.xlabel('城市',?fontsize=12)
plt.ylabel('崗位數(shù)',?fontsize=12)
#?展示圖片
plt.show()
運(yùn)行效果如下:
['上海',?'深圳',?'廣州',?'北京',?'杭州',?'成都',?'武漢',?'南京',?'蘇州',?'長(zhǎng)沙']
[2015,?1359,?999,?674,?550,?466,?457,?444,?320,?211]
上海、深圳、廣州、北京提供了很多崗位,杭州、成都、武漢、南京等城市的招聘崗位數(shù)量也比較可觀。
(2) 計(jì)算崗位數(shù)據(jù)的薪酬,處理為多少K/月,劃分薪酬區(qū)間,統(tǒng)計(jì)薪酬分布情況,餅圖展示。
代碼如下:
#?設(shè)置中文顯示
mpl.rcParams['font.family']?=?'SimHei'
#?設(shè)置大小??像素
plt.figure(figsize=(9,?6),?dpi=100)
plt.axes(aspect='equal')???#?保證餅圖是個(gè)正圓
explodes?=?[0,?0,?0,?0.1,?0.2,?0.3,?0.4,?0.5]
plt.pie(nums,?pctdistance=0.75,?shadow=True,
??colors=colors,?autopct='%.2f%%',?explode=explodes,
??startangle=15,?labeldistance=1.1,
??)
#?設(shè)置圖例???調(diào)節(jié)圖例位置
plt.legend(part_interval,?bbox_to_anchor=(1.0,?1.0))
plt.title('招聘崗位的薪酬分布',?fontsize=15)
plt.show()
運(yùn)行效果如下:
招聘崗位給的薪酬在5K-10K和10K-15K區(qū)間所占的比例較大,也有一定比例的50K以上的高薪資崗位。
(3) 查看招聘崗位對(duì)學(xué)歷的要求的情況,水平柱形圖可視化。
mport?pandas?as?pd
import?matplotlib.pyplot?as?plt
import?matplotlib?as?mpl
df?=?pd.read_csv(r'已清洗數(shù)據(jù).csv')['education']
data?=?df.value_counts()
labels?=?['大專',?'本科',?'碩士',?'博士']
nums?=?[data[i]?for?i?in?labels]
print(labels)
print(nums)
colors?=?['cyan',?'red',?'yellow',?'blue']
#?設(shè)置中文顯示
mpl.rcParams['font.family']?=?'SimHei'
#?設(shè)置顯示風(fēng)格
plt.style.use('ggplot')
#?設(shè)置大小??像素
plt.figure(figsize=(8,?6),?dpi=100)
#?繪制水平柱狀圖?
plt.barh(labels,?nums,?height=0.36,?color=colors)
plt.title('招聘崗位對(duì)學(xué)歷的要求',?fontsize=16)
plt.xlabel('崗位數(shù)量',?fontsize=12)
plt.show()
運(yùn)行效果如下:
['大專',?'本科',?'碩士',?'博士']
[2052,?6513,?761,?45]

(4) 查看招聘崗位對(duì)工作經(jīng)驗(yàn)的要求的情況,水平柱形圖可視化。
由于得到的工作經(jīng)驗(yàn)列里的數(shù)據(jù)并不規(guī)范,統(tǒng)計(jì)時(shí)需做特殊處理
代碼如下:
#?設(shè)置中文顯示
mpl.rcParams['font.family']?=?'SimHei'
#?設(shè)置顯示風(fēng)格
plt.style.use('ggplot')
#?設(shè)置大小??像素
plt.figure(figsize=(9,?6),?dpi=100)
#?繪制水平柱狀圖
plt.barh(labels,?nums,?height=0.5,?color=colors)
plt.title('招聘崗位對(duì)工作經(jīng)驗(yàn)的要求',?fontsize=16)
plt.xlabel('崗位數(shù)量',?fontsize=12)
plt.show()
運(yùn)行效果如下:
3-4年經(jīng)驗(yàn)??????3361
2年經(jīng)驗(yàn)????????2114
1年經(jīng)驗(yàn)????????1471
5-7年經(jīng)驗(yàn)??????1338
在校生\/應(yīng)屆生?????661
無(wú)需經(jīng)驗(yàn)?????????417
本科???????????182
8-9年經(jīng)驗(yàn)???????105
10年以上經(jīng)驗(yàn)???????64
碩士????????????59
招1人???????????57
招若干人??????????57
招2人???????????42
大專????????????30
招3人???????????14
博士????????????11
招5人????????????9
招4人????????????5
招10人???????????2
招7人????????????1
Name:?experience,?dtype:?int64
['無(wú)需經(jīng)驗(yàn)',?'1年經(jīng)驗(yàn)',?'2年經(jīng)驗(yàn)',?'3-4年經(jīng)驗(yàn)',?'5-7年經(jīng)驗(yàn)',?'8-9年經(jīng)驗(yàn)',?'10年以上經(jīng)驗(yàn)']
[1260,?1530,?2114,?3372,?1338,?105,?64]
【】#### (5) 查看招聘公司所屬行業(yè)的分布情況,詞云展示。
代碼如下:
import?pandas?as?pd
import?collections
from?wordcloud?import?WordCloud
import?matplotlib.pyplot?as?plt
df?=?pd.read_csv(r'已清洗數(shù)據(jù).csv')['category']
data?=?list(df.values)
word_list?=?[]
for?i?in?data:
????x?=?i.split('/')
????for?j?in?x:
????????word_list.append(j)
word_counts?=?collections.Counter(word_list)
#?繪制詞云
my_cloud?=?WordCloud(
????background_color='white',??#?設(shè)置背景顏色??默認(rèn)是black
????width=900,?height=500,
????font_path='simhei.ttf',????#?設(shè)置字體??顯示中文
????max_font_size=120,?????????#?設(shè)置字體最大值
????min_font_size=15,??????????#?設(shè)置子圖最小值
????random_state=60????????????#?設(shè)置隨機(jī)生成狀態(tài),即多少種配色方案
).generate_from_frequencies(word_counts)
#?顯示生成的詞云圖片
plt.imshow(my_cloud,?interpolation='bilinear')
#?顯示設(shè)置詞云圖中無(wú)坐標(biāo)軸
plt.axis('off')
plt.show()
運(yùn)行效果如下:
(6) 查看招聘崗位的職位福利,詞云展示。
代碼與上文一致
運(yùn)行效果如下:
職位福利關(guān)鍵詞中出現(xiàn)頻率較高的有五險(xiǎn)一金、年終獎(jiǎng)金、績(jī)效獎(jiǎng)金、定期體檢、餐飲補(bǔ)貼等。
源碼&數(shù)據(jù)下載
https://alltodata.cowtransfer.com/s/b1c87350fd8a47

