您現在的位置是:首頁 > 飲食

Python爬取招聘網站資料,給學習、求職一點參考

由 程式設計師程式設計分享 發表于 飲食2021-12-18
簡介DataFrame()df[“崗位名稱”] = job_namedf[“公司名稱”] = company_namedf[“工作地點”] = addressdf[“工資”] = salarydf[“釋出

dw中怎麼製作二級子頁面

1、專案背景

隨著科技的飛速發展,資料呈現爆發式的增長,任何人都擺脫不了與資料打交道,社會對於“資料”方面的人才需求也在不斷增大。因此瞭解當下企業究竟需要招聘什麼樣的人才?需要什麼樣的技能?不管是對於在校生,還是對於求職者來說,都顯得很有必要。

本文基於這個問題,針對51job招聘網站,爬取了全國範圍內大資料、資料分析、資料探勘、機器學習、人工智慧等相關崗位的招聘資訊。分析比較了不同崗位的薪資、學歷要求;分析比較了不同區域、行業對相關人才的需求情況;分析比較了不同崗位的知識、技能要求等。

做完以後的專案效果如下:

Python爬取招聘網站資料,給學習、求職一點參考

動態效果如下:

Python爬取招聘網站資料,給學習、求職一點參考

2、資訊的爬取

( 基於51job招聘網站的資料爬取)

當然小編這裡也準備一份適合你的學習資料爬蟲 ,web開發的學習資料影片教程,私信小編“01”都可以免費獲取!這些書籍都是可以私信小編“01”免費領取的!

Python爬取招聘網站資料,給學習、求職一點參考

爬取崗位:大資料、資料分析、機器學習、人工智慧等相關崗位;

爬取欄位:公司名、崗位名、工作地址、薪資、釋出時間、工作描述、公司型別、員工人數、所屬行業;

說明:基於51job招聘網站,我們搜尋全國對於“資料”崗位的需求,大概有2000頁。我們爬取的欄位,既有一級頁面的相關資訊,還有二級頁面的部分資訊;

爬取思路:先針對某一頁資料的一級頁面做一個解析,然後再進行二級頁面做一個解析,最後再進行翻頁操作;

使用工具:Python+requests+lxml+pandas+time

網站解析方式:Xpath

1)匯入相關庫

import requestsimport pandas as pdfrom pprint import pprintfrom lxml import etreeimport timeimport warningswarnings。filterwarnings(“ignore”)

2)關於翻頁的說明

# 第一頁的特點https://search。51job。com/list/000000,000000,0000,00,9,99,%25E6%2595%25B0%25E6%258D%25AE,2,1。html?# 第二頁的特點https://search。51job。com/list/000000,000000,0000,00,9,99,%25E6%2595%25B0%25E6%258D%25AE,2,2。html?# 第三頁的特點https://search。51job。com/list/000000,000000,0000,00,9,99,%25E6%2595%25B0%25E6%258D%25AE,2,3。html?

注意:透過對於頁面的觀察,可以看出,就一個地方的數字變化了,因此只需要做字串拼接,然後迴圈爬取即可。

3)完整的爬取程式碼

import requestsimport pandas as pdfrom pprint import pprintfrom lxml import etreeimport timeimport warningswarnings。filterwarnings(“ignore”)for i in range(1,1501): print(“正在爬取第” + str(i) + “頁的資料”) url_pre = “https://search。51job。com/list/000000,000000,0000,00,9,99,%25E6%2595%25B0%25E6%258D%25AE,2,” url_end = “。html?” url = url_pre + str(i) + url_end headers = { ‘User-Agent’: ‘Mozilla/5。0 (Windows NT 10。0; Win64; x64) AppleWebKit/537。36 (KHTML, like Gecko) Chrome/73。0。3683。86 Safari/537。36’ } web = requests。get(url, headers=headers) web。encoding = “gbk” dom = etree。HTML(web。text) # 1、崗位名稱 job_name = dom。xpath(‘//div[@class=“dw_table”]/div[@class=“el”]//p/span/a[@target=“_blank”]/@title’) # 2、公司名稱 company_name = dom。xpath(‘//div[@class=“dw_table”]/div[@class=“el”]/span[@class=“t2”]/a[@target=“_blank”]/@title’) # 3、工作地點 address = dom。xpath(‘//div[@class=“dw_table”]/div[@class=“el”]/span[@class=“t3”]/text()’) # 4、工資 salary_mid = dom。xpath(‘//div[@class=“dw_table”]/div[@class=“el”]/span[@class=“t4”]’) salary = [i。text for i in salary_mid] # 5、釋出日期 release_time = dom。xpath(‘//div[@class=“dw_table”]/div[@class=“el”]/span[@class=“t5”]/text()’) # 6、獲取二級網址url deep_url = dom。xpath(‘//div[@class=“dw_table”]/div[@class=“el”]//p/span/a[@target=“_blank”]/@href’) RandomAll = [] JobDescribe = [] CompanyType = [] CompanySize = [] Industry = [] for i in range(len(deep_url)): web_test = requests。get(deep_url[i], headers=headers) web_test。encoding = “gbk” dom_test = etree。HTML(web_test。text) # 7、爬取經驗、學歷資訊,先合在一個欄位裡面,以後再做資料清洗。命名為random_all random_all = dom_test。xpath(‘//div[@class=“tHeader tHjob”]//div[@class=“cn”]/p[@class=“msg ltype”]/text()’) # 8、崗位描述性息 job_describe = dom_test。xpath(‘//div[@class=“tBorderTop_box”]//div[@class=“bmsg job_msg inbox”]/p/text()’) # 9、公司型別 company_type = dom_test。xpath(‘//div[@class=“tCompany_sidebar”]//div[@class=“com_tag”]/p[1]/@title’) # 10、公司規模(人數) company_size = dom_test。xpath(‘//div[@class=“tCompany_sidebar”]//div[@class=“com_tag”]/p[2]/@title’) # 11、所屬行業(公司) industry = dom_test。xpath(‘//div[@class=“tCompany_sidebar”]//div[@class=“com_tag”]/p[3]/@title’) # 將上述資訊儲存到各自的列表中 RandomAll。append(random_all) JobDescribe。append(job_describe) CompanyType。append(company_type) CompanySize。append(company_size) Industry。append(industry) # 為了反爬,設定睡眠時間 time。sleep(1) # 由於我們需要爬取很多頁,為了防止最後一次性儲存所有資料出現的錯誤,因此,我們每獲取一夜的資料,就進行一次資料存取。 df = pd。DataFrame() df[“崗位名稱”] = job_name df[“公司名稱”] = company_name df[“工作地點”] = address df[“工資”] = salary df[“釋出日期”] = release_time df[“經驗、學歷”] = RandomAll df[“公司型別”] = CompanyType df[“公司規模”] = CompanySize df[“所屬行業”] = Industry df[“崗位描述”] = JobDescribe # 這裡在寫出過程中,有可能會寫入失敗,為了解決這個問題,我們使用異常處理。 try: df。to_csv(“job_info。csv”, mode=“a+”, header=None, index=None, encoding=“gbk”) except: print(“當頁資料寫入失敗”) time。sleep(1)print(“資料爬取完畢,是不是很開心!!!”)

這裡可以看到,我們爬取了1000多頁的資料做最終的分析。因此每爬取一頁的資料,做一次資料儲存,避免最終一次性儲存導致失敗。同時根據自己的測試,有一些頁數進行資料儲存,會導致失敗,為了不影響後面程式碼的執行,我們使用了“try-except”異常處理。

在一級頁面中,我們爬取了“崗位名稱”,“公司名稱”,“工作地點”,“工資”,“釋出日期”,“二級網址的url”這幾個欄位。

在二級頁面中,我們爬取了“經驗、學歷資訊”,“崗位描述”,“公司型別”,“公司規模”,“所屬行業”這幾個欄位。

3、資料預處理

從爬取到的資料中擷取部分做了一個展示,可以看出資料很亂。雜亂的資料並不利於我們的分析,因此需要根據研究的目標做一個數據預處理,得到我們最終可以用來做視覺化展示的資料。

1)相關庫的匯入及資料的讀取

df = pd。read_csv(r“G:\8泰迪\python_project\51_job\job_info1。csv”,engine=“python”,header=None)# 為資料框指定行索引df。index = range(len(df))# 為資料框指定列索引df。columns = [“崗位名”,“公司名”,“工作地點”,“工資”,“釋出日期”,“經驗與學歷”,“公司型別”,“公司規模”,“行業”,“工作描述”]

2)資料去重

我們認為一個公司的公司名和和釋出的崗位名一致,就看作是重複值。因此,使用drop_duplicates(subset=[])函式,基於“崗位名”和“公司名”做一個重複值的剔除。

# 去重之前的記錄數print(“去重之前的記錄數”,df。shape)# 記錄去重df。drop_duplicates(subset=[“公司名”,“崗位名”],inplace=True)# 去重之後的記錄數print(“去重之後的記錄數”,df。shape)

3)崗位名欄位的處理

① 崗位名欄位的探索

df[“崗位名”]。value_counts()df[“崗位名”] = df[“崗位名”]。apply(lambda x:x。lower())

說明:首先我們對每個崗位出現的頻次做一個統計,可以看出“崗位名欄位”太雜亂,不便於我們做統計分析。接著我們將崗位名中的大寫英文字母統一轉換為小寫字母,也就是說“AI”和“Ai”屬於同一個東西。

② 構造想要分析的目標崗位,做一個數據篩選

job_info。shapetarget_job = [‘演算法’, ‘開發’, ‘分析’, ‘工程師’, ‘資料’, ‘運營’, ‘運維’]index = [df[“崗位名”]。str。count(i) for i in target_job]index = np。array(index)。sum(axis=0) > 0job_info = df[index]job_info。shape

說明:首先我們構造瞭如上七個目標崗位的關鍵字眼。然後利用count()函式統計每一條記錄中,是否包含這七個關鍵字眼,如果包含就保留這個欄位,不過不包含就刪除這個欄位。最後檢視篩選之後還剩餘多少條記錄。

③ 目標崗位標準化處理(由於目標崗位太雜亂,我們需要統一一下)

job_list = [‘資料分析’, “資料統計”,“資料專員”,‘資料探勘’, ‘演算法’, ‘大資料’,‘開發工程師’, ‘運營’, ‘軟體工程’, ‘前端開發’, ‘深度學習’, ‘ai’, ‘資料庫’, ‘資料庫’, ‘資料產品’, ‘客服’, ‘java’, ‘。net’, ‘andrio’, ‘人工智慧’, ‘c++’, ‘資料管理’,“測試”,“運維”]job_list = np。array(job_list)def rename(x=None,job_list=job_list): index = [i in x for i in job_list] if sum(index) > 0: return job_list[index][0] else: return xjob_info[“崗位名”] = job_info[“崗位名”]。apply(rename)job_info[“崗位名”]。value_counts()# 資料統計、資料專員、資料分析統一歸為資料分析job_info[“崗位名”] = job_info[“崗位名”]。apply(lambda x:re。sub(“資料專員”,“資料分析”,x))job_info[“崗位名”] = job_info[“崗位名”]。apply(lambda x:re。sub(“資料統計”,“資料分析”,x))

說明:首先我們定義了一個想要替換的目標崗位job_list,將其轉換為ndarray陣列。然後定義一個函式,如果某條記錄包含job_list陣列中的某個關鍵詞,那麼就將該條記錄替換為這個關鍵詞,如果某條記錄包含job_list陣列中的多個關鍵詞,我們只取第一個關鍵詞替換該條記錄。接著使用value_counts()函式統計一下替換後的各崗位的頻次。最後,我們將“資料專員”、“資料統計”統一歸為“資料分析”。

4)工資水平欄位的處理

工資水平欄位的資料類似於“20-30萬/年”、“2。5-3萬/月”和“3。5-4。5千/月”這樣的格式。我們需要做一個統一的變化,將資料格式轉換為“元/月”,然後取出這兩個數字,求一個平均值。

job_info[“工資”]。str[-1]。value_counts()job_info[“工資”]。str[-3]。value_counts()index1 = job_info[“工資”]。str[-1]。isin([“年”,“月”])index2 = job_info[“工資”]。str[-3]。isin([“萬”,“千”])job_info = job_info[index1 & index2]def get_money_max_min(x): try: if x[-3] == “萬”: z = [float(i)*10000 for i in re。findall(“[0-9]+\。?[0-9]*”,x)] elif x[-3] == “千”: z = [float(i) * 1000 for i in re。findall(“[0-9]+\。?[0-9]*”, x)] if x[-1] == “年”: z = [i/12 for i in z] return z except: return xsalary = job_info[“工資”]。apply(get_money_max_min)job_info[“最低工資”] = salary。str[0]job_info[“最高工資”] = salary。str[1]job_info[“工資水平”] = job_info[[“最低工資”,“最高工資”]]。mean(axis=1)

說明:首先我們做了一個數據篩選,針對於每一條記錄,如果最後一個字在“年”和“月”中,同時第三個字在“萬”和“千”中,那麼就保留這條記錄,否則就刪除。接著定義了一個函式,將格式統一轉換為“元/月”。最後將最低工資和最高工資求平均值,得到最終的“工資水平”欄位。

5)工作地點欄位的處理

由於整個資料是關於全國的資料,涉及到的城市也是特別多。我們需要自定義一個常用的目標工作地點欄位,對資料做一個統一處理。

#job_info[“工作地點”]。value_counts()address_list = [‘北京’, ‘上海’, ‘廣州’, ‘深圳’, ‘杭州’, ‘蘇州’, ‘長沙’, ‘武漢’, ‘天津’, ‘成都’, ‘西安’, ‘東莞’, ‘合肥’, ‘佛山’, ‘寧波’, ‘南京’, ‘重慶’, ‘長春’, ‘鄭州’, ‘常州’, ‘福州’, ‘瀋陽’, ‘濟南’, ‘寧波’, ‘廈門’, ‘貴州’, ‘珠海’, ‘青島’, ‘中山’, ‘大連’,‘崑山’,“惠州”,“哈爾濱”,“昆明”,“南昌”,“無錫”]address_list = np。array(address_list)def rename(x=None,address_list=address_list): index = [i in x for i in address_list] if sum(index) > 0: return address_list[index][0] else: return xjob_info[“工作地點”] = job_info[“工作地點”]。apply(rename)

說明:首先我們定義了一個目標工作地點列表,將其轉換為ndarray陣列。接著定義了一個函式,將原始工作地點記錄,替換為目標工作地點中的城市。

6)公司型別欄位的處理

這個很容易,就不詳細說明了。

job_info。loc[job_info[“公司型別”]。apply(lambda x:len(x)<6),“公司型別”] = np。nanjob_info[“公司型別”] = job_info[“公司型別”]。str[2:-2]

7)行業欄位的處理

每個公司的行業欄位可能會有多個行業標籤,但是我們預設以第一個作為該公司的行業標籤。

# job_info[“行業”]。value_counts()job_info[“行業”] = job_info[“行業”]。apply(lambda x:re。sub(“,”,“/”,x))job_info。loc[job_info[“行業”]。apply(lambda x:len(x)<6),“行業”] = np。nanjob_info[“行業”] = job_info[“行業”]。str[2:-2]。str。split(“/”)。str[0]

8)經驗與學歷欄位的處理

關於這個欄位的資料處理,我很是思考了一會兒,不太好敘述,放上程式碼自己下去體會。

job_info[“學歷”] = job_info[“經驗與學歷”]。apply(lambda x:re。findall(“本科|大專|應屆生|在校生|碩士”,x))def func(x): if len(x) == 0: return np。nan elif len(x) == 1 or len(x) == 2: return x[0] else: return x[2]job_info[“學歷”] = job_info[“學歷”]。apply(func)

9)工作描述欄位的處理

對於每一行記錄,我們去除停用詞以後,做一個jieba分詞。

with open(r“G:\8泰迪\python_project\51_job\stopword。txt”,“r”) as f: stopword = f。read()stopword = stopword。split()stopword = stopword + [“任職”,“職位”,“ ”]job_info[“工作描述”] = job_info[“工作描述”]。str[2:-2]。apply(lambda x:x。lower())。apply(lambda x:“”。join(x))\ 。apply(jieba。lcut)。apply(lambda x:[i for i in x if i not in stopword])job_info。loc[job_info[“工作描述”]。apply(lambda x:len(x) < 6),“工作描述”] = np。nan

10)公司規模欄位的處理

#job_info[“公司規模”]。value_counts()def func(x): if x == “[‘少於50人’]”: return “<50” elif x == “[‘50-150人’]”: return “50-150” elif x == “[‘150-500人’]”: return ‘150-500’ elif x == “[‘500-1000人’]”: return ‘500-1000’ elif x == “[‘1000-5000人’]”: return ‘1000-5000’ elif x == “[‘5000-10000人’]”: return ‘5000-10000’ elif x == “[‘10000人以上’]”: return “>10000” else: return np。nanjob_info[“公司規模”] = job_info[“公司規模”]。apply(func)

11)構造新資料

我們針對最終清洗乾淨的資料,選取需要分析的欄位,做一個數據儲存。

feature = [“公司名”,“崗位名”,“工作地點”,“工資水平”,“釋出日期”,“學歷”,“公司型別”,“公司規模”,“行業”,“工作描述”]final_df = job_info[feature]final_df。to_excel(r“G:\8泰迪\python_project\51_job\詞雲圖。xlsx”,encoding=“gbk”,index=None)

4、關於“工作描述”欄位的特殊處理

由於我們之後需要針對不同的崗位名做不同的詞雲圖處理,並且是在tableau中做視覺化展示,因此我們需要按照崗位名分類,求出不同崗位下各關鍵詞的詞頻統計。

import numpy as npimport pandas as pdimport reimport jiebaimport warningswarnings。filterwarnings(“ignore”)df = pd。read_excel(r“G:\8泰迪\python_project\51_job\new_job_info1。xlsx”,encoding=“gbk”)dfdef get_word_cloud(data=None, job_name=None): words = [] describe = data[‘工作描述’][data[‘崗位名’] == job_name]。str[1:-1] describe。dropna(inplace=True) [words。extend(i。split(‘,’)) for i in describe] words = pd。Series(words) word_fre = words。value_counts() return word_frezz = [‘資料分析’, ‘演算法’, ‘大資料’,‘開發工程師’, ‘運營’, ‘軟體工程’,‘運維’, ‘資料庫’,‘java’,“測試”]for i in zz: word_fre = get_word_cloud(data=df, job_name=‘{}’。format(i)) word_fre = word_fre[1:]。reset_index()[:100] word_fre[“崗位名”] = pd。Series(“{}”。format(i),index=range(len(word_fre))) word_fre。to_csv(r“G:\8泰迪\python_project\51_job\詞雲圖\bb。csv”, mode=‘a’,index=False, header=None,encoding=“gbk”)

5、tableau視覺化展示

1) 熱門城市的用人需求TOP10

Python爬取招聘網站資料,給學習、求職一點參考

2)熱門城市的崗位數量TOP10

Python爬取招聘網站資料,給學習、求職一點參考

3)不同工作地點崗位數量的氣泡圖

Python爬取招聘網站資料,給學習、求職一點參考

4)熱門崗位的薪資待遇

Python爬取招聘網站資料,給學習、求職一點參考

5)熱門行業的薪資待遇

Python爬取招聘網站資料,給學習、求職一點參考

6)視覺化大屏的最終展示

Python爬取招聘網站資料,給學習、求職一點參考

7)視覺化大屏的“動態”展示

Python爬取招聘網站資料,給學習、求職一點參考

說明:這裡最終就不做結論分析了,因為結論透過上圖,就可以很清晰的看出來。

推薦文章

  • 「吉林市」吉林市農業農村局組織熊蜂授粉助農民增產增收

    「吉林市」吉林市農業農村局組織熊蜂授粉助農民增產增收據介紹,這兩箱價值700餘元的專業授粉熊蜂是按照《農業農村部辦公廳關於實施蜂業質量提升行動的通知》及吉林省畜牧總站《2022年吉林省蜂授粉技術推廣與市場培育專案實施方案》等檔案精神,由吉林省養蜂科學研究所與吉林市農業農村局免費提供的...

  • 蘭蔻極光水一週用幾次

    蘭蔻極光水是一款既可以當做精華使用又可以當作化妝水使用的護膚產品,有煥亮膚色、細膩肌膚、促進新陳代謝、平衡肌膚油脂的功效與作用,適用於任何年齡段,有淡斑需求的女性使用...

  • 牛奶紅豆這樣煮,奶香味濃郁,比奶茶好喝百倍,好吃又不長胖

    這道菜的味道很好,味道也很好聞,而且很容易製作,不需要到咖啡廳裡,自己就能做出來,而且還很美味,而且還很健康,只要學會了西米的烹飪方法,就可以輕鬆地製作成一碗熱氣騰騰的飲料...