成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

前程無憂崗位數(shù)據(jù)爬取+Tableau可視化分析

233jl / 2333人閱讀

摘要:實際上,前程無憂招聘網(wǎng)站上與數(shù)據(jù)有關(guān)的只有幾百頁,而我們爬取了頁的所有數(shù)據(jù),因此在后面進(jìn)行數(shù)據(jù)處理時需要把無關(guān)的數(shù)據(jù)剔除掉。

目錄

一、項目背景

二、數(shù)據(jù)爬取

1、相關(guān)庫的導(dǎo)入與說明

2、獲取二級頁面鏈接

1)分析一級頁面url特征

2)構(gòu)建一級url庫

3)爬取所有二級url鏈接

3、獲取崗位信息并保存

三、數(shù)據(jù)清洗

1、數(shù)據(jù)讀取、去重、空值處理

1)相關(guān)庫導(dǎo)入及數(shù)據(jù)讀取

2)數(shù)據(jù)去重與控制處理

2、“崗位名稱”字段預(yù)處理

1)”崗位名稱“字段預(yù)覽

2)構(gòu)建關(guān)鍵詞,篩選名稱

3)崗位名稱標(biāo)準(zhǔn)化處理

3、“崗位薪資”字段預(yù)處理

4、“公司規(guī)模”字段預(yù)處理

5、“職位信息”字段預(yù)處理

6、其它字段預(yù)處理

7、數(shù)據(jù)存儲

四、Tableau數(shù)據(jù)可視化展示

1、崗位數(shù)量城市分布?xì)馀輬D

2、熱門城市用人需求Top15

?3、用人需求Top15行業(yè)及其薪資情況

4、各類型企業(yè)崗位需求樹狀分布圖

5、經(jīng)驗學(xué)歷與薪資需求突出顯示表?

6、不同行業(yè)知識、技能要求詞云圖

1)傳統(tǒng)制造業(yè)

2) 計算機(jī)相關(guān)行業(yè)

3)服務(wù)行業(yè)?

6、崗位數(shù)量與薪資水平地理分布

7、可視化看板最終展示結(jié)果

五、源代碼

1、爬蟲源代碼

2、數(shù)據(jù)預(yù)處理源碼


一、項目背景

????????隨著科技的不斷進(jìn)步與發(fā)展,數(shù)據(jù)呈現(xiàn)爆發(fā)式的增長,各行各業(yè)對于數(shù)據(jù)的依賴越來越強(qiáng),與數(shù)據(jù)打交道在所難免,而社會對于“數(shù)據(jù)”方面的人才需求也在不斷增大。因此了解當(dāng)下企業(yè)究竟需要招聘什么樣的人才?需要什么樣的技能?不管是對于在校生,還是對于求職者來說,都顯得十分必要。
? ? ? ? 對于一名小白來說,想要入門數(shù)據(jù)分析,首先要了解目前社會對于數(shù)據(jù)相關(guān)崗位的需求情況,基于這一問題,本文針對前程無憂招聘網(wǎng)站,利用python爬取了其全國范圍內(nèi)大數(shù)據(jù)、數(shù)據(jù)分析、數(shù)據(jù)挖掘、機(jī)器學(xué)習(xí)、人工智能等與數(shù)據(jù)相關(guān)的崗位招聘信息。并通過Tableau可視化工具分析比較了不同行業(yè)的崗位薪資、用人需求等情況;以及不同行業(yè)、崗位的知識、技能要求等。

? ? ? ? ?可視化分析效果圖示例:

二、數(shù)據(jù)爬取

  • 爬取字段:崗位名稱、公司名稱、薪資水平、工作經(jīng)驗、學(xué)歷需求、工作地點、招聘人數(shù)、發(fā)布時間、公司類型、公司規(guī)模、行業(yè)領(lǐng)域、福利待遇、職位信息;
  • 說明:在前程無憂招聘網(wǎng)站中,我們在搜索框中輸入“數(shù)據(jù)”兩個字進(jìn)行搜索發(fā)現(xiàn),共有2000個一級頁面,其中每個頁面包含50條崗位信息,因此總共有約100000條招聘信息。當(dāng)點擊一級頁面中每個崗位信息時,頁面會跳轉(zhuǎn)至相應(yīng)崗位的二級頁面,二級頁面中即包含我們所需要的全部字段信息;

????????一級頁面如下:

????????二級頁面如下:

  • 爬取思路:先針對一級頁面爬取所有崗位對應(yīng)的二級頁面鏈接,再根據(jù)二級頁面鏈接遍歷爬取相應(yīng)崗位信息;
  • 開發(fā)環(huán)境:python3、Spyder

1、相關(guān)庫的導(dǎo)入與說明

import jsonimport requestsimport pandas as pdfrom selenium import webdriverfrom selenium.webdriver.common.by import Byfrom selenium.webdriver.support.ui import WebDriverWaitfrom selenium.webdriver.support import expected_conditions as ECfrom lxml import etreefrom selenium.webdriver import ChromeOptions

? ? ? ? 由于前程無憂招聘網(wǎng)站的反爬機(jī)制較強(qiáng),采用動態(tài)渲染+限制ip訪問頻率等多層反爬,因此在獲取二級頁面鏈接時需借助json進(jìn)行解析,本文對于二級頁面崗位信息的獲取采用selenium模擬瀏覽器爬取,同時通過代理IP的方式,每隔一段時間換一次請求IP以免觸發(fā)網(wǎng)站反爬機(jī)制。?

2、獲取二級頁面鏈接

1)分析一級頁面url特征

# 第一頁URL的特征"https://search.51job.com/list/000000,000000,0000,00,9,99,數(shù)據(jù),2,1.html?"# 第二頁URL的特征"https://search.51job.com/list/000000,000000,0000,00,9,99,數(shù)據(jù),2,2.html?"# 第三頁URL的特征"https://search.51job.com/list/000000,000000,0000,00,9,99,數(shù)據(jù),2,3.html?"

? ? ? ? 通過觀察不同頁面的URL可以發(fā)現(xiàn),不同頁面的URL鏈接只有“.html”前面的數(shù)字不同,該數(shù)字正好代表該頁的頁碼?,因此只需要構(gòu)造字符串拼接,然后通過for循環(huán)語句即可構(gòu)造自動翻頁。

2)構(gòu)建一級url庫

url1 = []for i in range(2000):    url_pre = "https://search.51job.com/list/000000,000000,0000,00,9,99,數(shù)據(jù),2,%s" % (1+i) #設(shè)置自動翻頁       url_end = ".html?"    url_all = url_pre + url_end    url1.append(url_all)print("一級URL庫創(chuàng)建完畢")

3)爬取所有二級url鏈接

url2 = []j = 0for url in url1:    j += 1    re1 = requests.get(url , headers = headers,proxies= {"http":"tps131.kdlapi.com:15818"},timeout=(5,10))  #通過proxies設(shè)置代理ip    html1 = etree.HTML(re1.text)        divs = html1.xpath("http://script[@type = "text/javascript"]/text()")[0].replace("window.__SEARCH_RESULT__ = ","")        js = json.loads(divs)    for i in range(len(js["engine_jds"])):        if js["engine_jds"][i]["job_href"][0:22] == "https://jobs.51job.com":            url2.append(js["engine_jds"][i]["job_href"])        else:            print("url異常,棄用")  #剔除異常url    print("已爬取"+str(j)+"頁")print("成功爬取"+str(len(url2))+"條二級URL")

注意:爬取二級URL鏈接時發(fā)現(xiàn)并非爬取的所有鏈接都是規(guī)范的,會存在少部分異常URL,這會對后續(xù)崗位信息的爬取造成干擾,因此需要利用if條件語句對其進(jìn)行剔除。

3、獲取崗位信息并保存

option = ChromeOptions()option.add_experimental_option("excludeSwitches", ["enable-automation"])option.add_argument("--proxy-server=http://tps131.kdlapi.com:15818")  #設(shè)置代理ipdriver = webdriver.Chrome(options=option)for url in url2:    co = 1    while co == 1:        try:            driver.get(url)            wait = WebDriverWait(driver,10,0.5)            wait.until(EC.presence_of_element_located((By.ID,"topIndex")))        except:            driver.close()            driver = webdriver.Chrome(options=option)            co = 1        else:            co = 0    try:        福利待遇 = driver.find_elements_by_xpath("http://div[@class = "t1"]")[0].text         崗位名稱 = driver.find_element_by_xpath("http://div[@class = "cn"]/h1").text        薪資水平 = driver.find_element_by_xpath("http://div[@class = "cn"]/strong").text        職位信息 = driver.find_elements_by_xpath("http://div[@class = "bmsg job_msg inbox"]")[0].text        公司類型 = driver.find_elements_by_xpath("http://div[@class = "com_tag"]/p")[0].text        公司規(guī)模 = driver.find_elements_by_xpath("http://div[@class = "com_tag"]/p")[1].text        公司領(lǐng)域 = driver.find_elements_by_xpath("http://div[@class = "com_tag"]/p")[2].text        公司名稱 = driver.find_element_by_xpath("http://div[@class = "com_msg"]/a/p").text        工作地點 = driver.find_elements_by_xpath("http://div[@class = "cn"]//p[@class = "msg ltype"]")[0].text.split("|")[0]        工作經(jīng)驗 = driver.find_elements_by_xpath("http://div[@class = "cn"]//p[@class = "msg ltype"]")[0].text.split("|")[1]        學(xué)歷要求 = driver.find_elements_by_xpath("http://div[@class = "cn"]//p[@class = "msg ltype"]")[0].text.split("|")[2]        招聘人數(shù) = driver.find_elements_by_xpath("http://div[@class = "cn"]//p[@class = "msg ltype"]")[0].text.split("|")[3]        發(fā)布時間 = driver.find_elements_by_xpath("http://div[@class = "cn"]//p[@class = "msg ltype"]")[0].text.split("|")[4]    except:        福利待遇 = "nan"         崗位名稱 = "nan"        薪資水平 = "nan"        職位信息 = "nan"        公司類型 = "nan"        公司規(guī)模 = "nan"        公司領(lǐng)域 = "nan"        公司名稱 = "nan"        工作地點 = "nan"        工作經(jīng)驗 = "nan"        學(xué)歷要求 = "nan"        招聘人數(shù) = "nan"        發(fā)布時間 = "nan"        print("信息提取異常,棄用")    finally:             info = {                "崗位名稱" : 崗位名稱,            "公司名稱" : 公司名稱,            "薪資水平" : 薪資水平,            "工作經(jīng)驗" : 工作經(jīng)驗,            "學(xué)歷要求" : 學(xué)歷要求,            "工作地點" : 工作地點,            "招聘人數(shù)" : 招聘人數(shù),            "發(fā)布時間" : 發(fā)布時間,            "公司類型" : 公司類型,            "公司規(guī)模" : 公司規(guī)模,            "公司領(lǐng)域" : 公司領(lǐng)域,            "福利待遇" : 福利待遇,            "職位信息" : 職位信息            }        jobs_info.append(info)df = pd.DataFrame(jobs_info)df.to_excel(r"E:/python爬蟲/前程無憂招聘信息.xlsx") 

? ? ? ? 在爬取并剔除異常數(shù)據(jù)之后,最終得到了90000多條完整的數(shù)據(jù)做分析,但經(jīng)過觀察發(fā)現(xiàn),所爬取的數(shù)據(jù)并非全都與“數(shù)據(jù)”崗位相關(guān)聯(lián)。實際上,前程無憂招聘網(wǎng)站上與“數(shù)據(jù)”有關(guān)的只有幾百頁,而我們爬取了2000頁的所有數(shù)據(jù),因此在后面進(jìn)行數(shù)據(jù)處理時需要把無關(guān)的數(shù)據(jù)剔除掉。在爬取前根據(jù)對代碼的測試發(fā)現(xiàn),有些崗位字段在進(jìn)行爬取時會出現(xiàn)錯位,從而導(dǎo)致數(shù)據(jù)存儲失敗,為了不影響后面代碼的執(zhí)行,這里設(shè)置了“try-except”進(jìn)行異常處理,同時使用while循環(huán)語句在服務(wù)器出現(xiàn)請求失敗時關(guān)閉模擬瀏覽器并進(jìn)行重新請求。

三、數(shù)據(jù)清洗

1、數(shù)據(jù)讀取、去重、空值處理

????????在獲取了所需數(shù)據(jù)之后,可以看出數(shù)據(jù)較亂,并不利于我們進(jìn)行分析,因此在分析前需要對數(shù)據(jù)進(jìn)行預(yù)處理,得到規(guī)范格式的數(shù)據(jù)才可以用來最終做可視化數(shù)據(jù)展示。

? ? ? ? 獲取的數(shù)據(jù)截圖如下:

1)相關(guān)庫導(dǎo)入及數(shù)據(jù)讀取

#導(dǎo)入相關(guān)庫import pandas as pdimport numpy as npimport jieba#讀取數(shù)據(jù)df = pd.read_excel(r"E:/python爬蟲/前程無憂招聘信息.xlsx",index_col=0)

2)數(shù)據(jù)去重與控制處理

  • 對于重復(fù)值的定義,我們認(rèn)為一個記錄的公司名稱和崗位名稱一致時,即可看作是重復(fù)值。因此利用drop_duplicates()函數(shù)剔除所有公司名稱和崗位名稱相同的記錄并保留第一個記錄。
  • 對于空值處理,只刪除所有字段信息都為nan的記錄。
#去除重復(fù)數(shù)據(jù)df.drop_duplicates(subset=["公司名稱","崗位名稱"],inplace=True)#空值刪除df[df["公司名稱"].isnull()]df.dropna(how="all",inplace=True)

2、“崗位名稱”字段預(yù)處理

1)”崗位名稱“字段預(yù)覽

? ? ? ? 首先我們對“崗位名稱”的格式進(jìn)行調(diào)整,將其中所有大寫英文字母統(tǒng)一轉(zhuǎn)換為小寫,例如將"Java"轉(zhuǎn)換為"java",然后對所有崗位做一個頻次統(tǒng)計,統(tǒng)計結(jié)果發(fā)現(xiàn)“崗位名稱”字段很雜亂,且存在很多與“數(shù)據(jù)”無關(guān)的崗位,因此要對數(shù)據(jù)做一個篩選。

df["崗位名稱"] = df["崗位名稱"].apply(lambda x:x.lower())counts = df["崗位名稱"].value_counts() 

2)構(gòu)建關(guān)鍵詞,篩選名稱

? ? ? ? 首先我們列出與“數(shù)據(jù)”崗位“有關(guān)的一系列關(guān)鍵詞,然后通過count()與for語句對所有記錄進(jìn)行統(tǒng)計判斷,如果包含任一關(guān)鍵詞則保留該記錄,如果不包含則刪除該字段。

#構(gòu)建目標(biāo)關(guān)鍵詞target_job = ["算法","開發(fā)","分析","工程師","數(shù)據(jù)","運營","運維","it","倉庫","統(tǒng)計"]#篩選目標(biāo)數(shù)據(jù)index = [df["崗位名稱"].str.count(i) for i in target_job]index = np.array(index).sum(axis=0) > 0job_info = df[index]

3)崗位名稱標(biāo)準(zhǔn)化處理

? ? ? ? 基于前面對“崗位名稱”字段的統(tǒng)計情況,我們定義了目標(biāo)崗位列表job_list,用來替換統(tǒng)一相近的崗位名稱,之后,我們將“數(shù)據(jù)專員”、“數(shù)據(jù)統(tǒng)計”統(tǒng)一歸為“數(shù)據(jù)分析”。

job_list = ["數(shù)據(jù)分析","數(shù)據(jù)統(tǒng)計","數(shù)據(jù)專員","數(shù)據(jù)挖掘","算法","大數(shù)據(jù)","開發(fā)工程師","運營",            "軟件工程","前端開發(fā)","深度學(xué)習(xí)","ai","數(shù)據(jù)庫","倉庫管理","數(shù)據(jù)產(chǎn)品","客服",            "java",".net","andrio","人工智能","c++","數(shù)據(jù)管理","測試","運維","數(shù)據(jù)工程師"]job_list = np.array(job_list)def Rename(x,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["崗位名稱"] = job_info["崗位名稱"].apply(lambda x:x.replace("數(shù)據(jù)專員","數(shù)據(jù)分析"))job_info["崗位名稱"] = job_info["崗位名稱"].apply(lambda x:x.replace("數(shù)據(jù)統(tǒng)計","數(shù)據(jù)分析"))

? ? ? ? 統(tǒng)一之后的“崗位名稱”如下圖所示:

?

3、“崗位薪資”字段預(yù)處理

? ? ? ? 對于“崗位薪資”字段的處理,重點在于對其單位格式轉(zhuǎn)換,在簡單觀察該字段后發(fā)現(xiàn),其存在“萬/年”、“萬/月”、“千/月”等不同單位,因此需要對其做一個統(tǒng)一換算,將數(shù)據(jù)格式統(tǒng)一轉(zhuǎn)換為“元/月”,并根據(jù)最高工資與最低工資求出平均值。

job_info["崗位薪資"].value_counts()#剔除異常數(shù)據(jù)index1 = job_info["崗位薪資"].str[-1].isin(["年","月"])index2 = job_info["崗位薪資"].str[-3].isin(["萬","千"])job_info = job_info[index1 & index2]#計算平均工資job_info["平均薪資"] = job_info["崗位薪資"].astype(str).apply(lambda x:np.array(x[:-3].split("-"),dtype=float))job_info["平均薪資"] = job_info["平均薪資"].apply(lambda x:np.mean(x))#統(tǒng)一工資單位job_info["單位"] = job_info["崗位薪資"].apply(lambda x:x[-3:])def con_unit(x):    if x["單位"] == "萬/月":        z = x["平均薪資"]*10000    elif x["單位"] == "千/月":        z = x["平均薪資"]*1000    elif x["單位"] == "萬/年":        z = x["平均薪資"]/12*10000    return int(z)job_info["平均薪資"] = job_info.apply(con_unit,axis=1)job_info["單位"] = "元/月"

說明:首先我們對該字段進(jìn)行統(tǒng)計預(yù)覽,之后做一個數(shù)據(jù)篩選剔除異常單位與空值記錄,再計算出每個字段的平均工資,接著定義一個函數(shù),將格式換算為“元/月”,得到最終的“平均薪資”字段。

4、“公司規(guī)模”字段預(yù)處理

? ? ? ? 對于“公司規(guī)?!弊侄蔚奶幚磔^簡單,只需要定義一個if條件語句將其格式做一個轉(zhuǎn)換即可。

job_info["公司規(guī)模"].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["公司規(guī)模"] = job_info["公司規(guī)模"].apply(func)

5、“職位信息”字段預(yù)處理

job_info["職位信息"] = job_info["職位信息"].apply(lambda x:x.split("職能類別")[0])with open(r"E:/python爬蟲/數(shù)據(jù)處理/停用詞表.txt","r",encoding = "utf8") as f:    stopword = f.read()stopword = stopword.split()#對“職業(yè)信息”字段進(jìn)行簡單處理,去除無意義的文字,構(gòu)造jieba分詞job_info["職位信息"] = job_info["職位信息"].apply(lambda x:x.lower()).apply(lambda x:"".join(x)).apply(lambda x:x.strip()).apply(jieba.lcut).apply(lambda x:[i for i in x if i not in stopword])#按照行業(yè)進(jìn)行分類,求出每一個行業(yè)下各關(guān)鍵詞的詞頻統(tǒng)計,以便于后期做詞云圖cons = job_info["公司領(lǐng)域"].value_counts()industries = pd.DataFrame(cons.index,columns=["行業(yè)領(lǐng)域"])industry = pd.DataFrame(columns=["分詞明細(xì)","行業(yè)領(lǐng)域"])for i in industries["行業(yè)領(lǐng)域"]:    words = []    word = job_info["職位信息"][job_info["公司領(lǐng)域"] == i]    word.dropna(inplace=True)    [words.extend(str(z).strip("/"[]").split("/", /"")) for z in word]    df1 = pd.DataFrame({"分詞明細(xì)":words,                        "行業(yè)領(lǐng)域":i})    industry = industry.append(df1,ignore_index=True)industry = industry[industry["分詞明細(xì)"] != "http://n"]industry = industry[industry["分詞明細(xì)"] != ""]#剔除詞頻小于300的關(guān)鍵詞count = pd.DataFrame(industry["分詞明細(xì)"].value_counts())lst = list(count[count["分詞明細(xì)"] >=300].index)industry = industry[industry["分詞明細(xì)"].isin(lst)]#數(shù)據(jù)存儲industry.to_excel(r"E:/python爬蟲/數(shù)據(jù)處理/詞云.xlsx")   

6、其它字段預(yù)處理

  • “工作地點”字段:該字段有”市-區(qū)“和”市“兩種格式,如”廣州-天河“與”廣州“,因此需要統(tǒng)一轉(zhuǎn)換為”市“的格式;
  • “公司領(lǐng)域”字段:每個公司的行業(yè)字段可能會有多個行業(yè)標(biāo)簽,我們默認(rèn)以第一個作為改公司的行業(yè)標(biāo)簽;
  • “招聘人數(shù)”字段:由于某些公司崗位沒有具體招聘人數(shù),因此我們默認(rèn)以最低需求為標(biāo)準(zhǔn),將“招若干人”改為“招1人”,以便于后面統(tǒng)計分析;
  • 其它字段:對于其他幾個字段格式只存在一些字符串空格問題,因此只需要對其進(jìn)行去除空格即可。
#工作地點字段處理job_info["工作地點"] = job_info["工作地點"].apply(lambda x:x.split("-")[0])#公司領(lǐng)域字段處理job_info["公司領(lǐng)域"] = job_info["公司領(lǐng)域"].apply(lambda x:x.split("/")[0])a = job_info["公司領(lǐng)域"].value_counts()#招聘人數(shù)字段處理job_info["招聘人數(shù)"] = job_info["招聘人數(shù)"].apply(lambda x:x.replace("若干","1").strip()[1:-1])#工作經(jīng)驗與學(xué)歷要求字段處理job_info["工作經(jīng)驗"] = job_info["工作經(jīng)驗"].apply(lambda x:x.replace("無需","1年以下").strip()[:-2])job_info["學(xué)歷需求"] = job_info["學(xué)歷需求"].apply(lambda x:x.split()[0])#公司福利字段處理job_info["公司福利"] = job_info["公司福利"].apply(lambda x:str(x).split())

7、數(shù)據(jù)存儲

? ? ? ? 我們針對清洗干凈后的數(shù)據(jù)另存為一個文檔,對源數(shù)據(jù)不做修改。

job_info.to_excel(r"E:/python爬蟲/前程無憂(已清洗).xlsx")

四、Tableau數(shù)據(jù)可視化展示

1、崗位數(shù)量城市分布?xì)馀輬D

結(jié)論分析:從氣泡圖中可以看出,“數(shù)據(jù)”相關(guān)崗位數(shù)量較高的城市有:上海、深圳、廣州、北京、杭州、武漢等。

2、熱門城市用人需求Top15

結(jié)論分析:通過條形圖可以看出,“數(shù)據(jù)”相關(guān)崗位用人需求達(dá)1000人以上的城市有15個,需求由高到低依次為:上海、深圳、廣州、北京、武漢、杭州、成都、南京、蘇州、無錫、西安、長沙、鄭州、重慶。其中上海用人需求高達(dá)10000人。

?3、用人需求Top15行業(yè)及其薪資情況

結(jié)論分析:從不同行業(yè)的用人需求與薪資對比可知,用人需求排名前4的行業(yè)分別:計算機(jī)軟件、互聯(lián)網(wǎng)、電子技術(shù)、計算機(jī)服務(wù);平均薪資排名前4的行業(yè)分別為:互聯(lián)網(wǎng)、計算機(jī)軟件、通信、專業(yè)服務(wù)。可以發(fā)現(xiàn),“數(shù)據(jù)”相關(guān)崗位在計算機(jī)領(lǐng)域需求大,薪資高,前景好。

4、各類型企業(yè)崗位需求樹狀分布圖

結(jié)論分析:在發(fā)布的眾多崗位需求信息中,以民營公司為主,其崗位數(shù)量、用人需求極高,但薪資待遇一般,而上市公司的崗位數(shù)量一般,但薪資待遇好。

5、經(jīng)驗學(xué)歷與薪資需求突出顯示表?

????????注:顏色深淺表示薪資高低,數(shù)字表示招聘人數(shù)

結(jié)論分析:根據(jù)突出顯示表可以發(fā)現(xiàn),在學(xué)歷要求方面,大專與本科生需求量較大;經(jīng)驗要求方面,3年以下相關(guān)經(jīng)驗的崗位占大多數(shù),而薪資方面,學(xué)歷越高,經(jīng)驗越豐富則薪資越高。因此可以判斷數(shù)據(jù)分析行業(yè)還是一個較新興的行業(yè),目前行業(yè)的基礎(chǔ)崗位較多,且具有豐富經(jīng)驗的專家較少。

6、不同行業(yè)知識、技能要求詞云圖

1)傳統(tǒng)制造業(yè)

2) 計算機(jī)相關(guān)行業(yè)

3)服務(wù)行業(yè)

?結(jié)論分析:上圖通過列舉了傳統(tǒng)制造業(yè)、計算機(jī)相關(guān)行業(yè)以及服務(wù)業(yè)三個行業(yè)進(jìn)行對比分析,三個行業(yè)對于“數(shù)據(jù)”相關(guān)崗位工作要求的共同點都是注重相關(guān)的行業(yè)經(jīng)驗及數(shù)據(jù)處理等能力,而計算機(jī)相關(guān)行業(yè)對于技術(shù)如開發(fā)、數(shù)據(jù)庫、系統(tǒng)維護(hù)等編程能力要求較高,傳統(tǒng)制造業(yè)和服務(wù)行業(yè)則更側(cè)重于業(yè)務(wù)分析、管理、團(tuán)隊合作綜合型能力等。

6、崗位數(shù)量與薪資水平地理分布

7、可視化看板最終展示結(jié)果

?

五、源代碼

1、爬蟲源代碼

import jsonimport requestsimport pandas as pdfrom lxml import etreefrom selenium import webdriverfrom selenium.webdriver.common.by import Byfrom selenium.webdriver import ChromeOptionsfrom selenium.webdriver.support.ui import WebDriverWaitfrom selenium.webdriver.support import expected_conditions as ECurl1 = []url2 = []jobs_info = []for i in range(2000):    url_pre = "https://search.51job.com/list/000000,000000,0000,00,9,99,數(shù)據(jù),2,%s" % (1+i)    #頁面跳轉(zhuǎn)    url_end = ".html?"    url_all = url_pre + url_end    url1.append(url_all)print("一級URL庫創(chuàng)建完畢")#從json中提取數(shù)據(jù)并加載headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.63 Safari/537.36",           "Connection": "close",           "Host": "search.51job.com"}j = 0for url in url1:    j += 1    re1 = requests.get(url , headers = headers,proxies= {"http":"tps131.kdlapi.com:15818"},timeout=(5,10))    html1 = etree.HTML(re1.text)        divs = html1.xpath("http://script[@type = "text/javascript"]/text()")[0].replace("window.__SEARCH_RESULT__ = ","")        js = json.loads(divs)    for i in range(len(js["engine_jds"])):        if js["engine_jds"][i]["job_href"][0:22] == "https://jobs.51job.com":            url2.append(js["engine_jds"][i]["job_href"])        else:            print("url異常,棄用")    print("已解析"+str(j)+"頁")print("成功提取"+str(len(url2))+"條二級URL")#爬取崗位數(shù)據(jù)option = ChromeOptions()option.add_experimental_option("excludeSwitches", ["enable-automation"])option.add_argument("--proxy-server=http://tps131.kdlapi.com:15818") driver = webdriver.Chrome(options=option)for url in url2:    co = 1    while co == 1:        try:             #設(shè)置IP代理            driver.get(url)            wait = WebDriverWait(driver,10,0.5)            wait.until(EC.presence_of_element_located((By.ID,"topIndex")))        except:            driver.close()            driver = webdriver.Chrome(options=option)            co = 1        else:            co = 0    try:        福利待遇 = driver.find_elements_by_xpath("http://div[@class = "t1"]")[0].text         崗位名稱 = driver.find_element_by_xpath("http://div[@class = "cn"]/h1").text        薪資水平 = driver.find_element_by_xpath("http://div[@class = "cn"]/strong").text        職位信息 = driver.find_elements_by_xpath("http://div[@class = "bmsg job_msg inbox"]")[0].text        公司類型 = driver.find_elements_by_xpath("http://div[@class = "com_tag"]/p")[0].text        公司規(guī)模 = driver.find_elements_by_xpath("http://div[@class = "com_tag"]/p")[1].text        公司領(lǐng)域 = driver.find_elements_by_xpath("http://div[@class = "com_tag"]/p")[2].text        公司名稱 = driver.find_element_by_xpath("http://div[@class = "com_msg"]/a/p").text        工作地點 = driver.find_elements_by_xpath("http://div[@class = "cn"]//p[@class = "msg ltype"]")[0].text.split("|")[0]        工作經(jīng)驗 = driver.find_elements_by_xpath("http://div[@class = "cn"]//p[@class = "msg ltype"]")[0].text.split("|")[1]        學(xué)歷要求 = driver.find_elements_by_xpath("http://div[@class = "cn"]//p[@class = "msg ltype"]")[0].text.split("|")[2]        招聘人數(shù) = driver.find_elements_by_xpath("http://div[@class = "cn"]//p[@class = "msg ltype"]")[0].text.split("|")[3]        發(fā)布時間 = driver.find_elements_by_xpath("http://div[@class = "cn"]//p[@class = "msg ltype"]")[0].text.split("|")[4]    except:        福利待遇 = "nan"         崗位名稱 = "nan"        薪資水平 = "nan"        職位信息 = "nan"        公司類型 = "nan"        公司規(guī)模 = "nan"        公司領(lǐng)域 = "nan"        公司名稱 = "nan"        工作地點 = "nan"        工作經(jīng)驗 = "nan"        學(xué)歷要求 = "nan"        招聘人數(shù) = "nan"        發(fā)布時間 = "nan"        print("信息提取異常,棄用")    finally:             info = {                "崗位名稱" : 崗位名稱,            "公司名稱" : 公司名稱,            "薪資水平" : 薪資水平,            "工作經(jīng)驗" : 工作經(jīng)驗,            "學(xué)歷要求" : 學(xué)歷要求,            "工作地點" : 工作地點,            "招聘人數(shù)" : 招聘人數(shù),            "發(fā)布時間" : 發(fā)布時間,            "公司類型" : 公司類型,            "公司規(guī)模" : 公司規(guī)模,            "公司領(lǐng)域" : 公司領(lǐng)域,            "福利待遇" : 福利待遇,            "職位信息" : 職位信息            }        jobs_info.append(info)df = pd.DataFrame(jobs_info)df.to_excel(r"E:/python爬蟲/前程無憂招聘信息.xlsx") 

2、數(shù)據(jù)預(yù)處理源碼

import pandas as pdimport numpy as npimport jieba#數(shù)據(jù)讀取df = pd.read_excel(r"E:/python爬蟲/前程無憂招聘信息.xlsx",index_col=0)#數(shù)據(jù)去重與空值處理df.drop_duplicates(subset=["公司名稱","崗位名稱"],inplace=True)df[df["招聘人數(shù)"].isnull()]df.dropna(how="all",inplace=True)#崗位名稱字段處理df["崗位名稱"] = df["崗位名稱"].apply(lambda x:x.lower())counts = df["崗位名稱"].value_counts() target_job = ["算法","開發(fā)","分析","工程師","數(shù)據(jù)","運營","運維","it","倉庫","統(tǒng)計"]index = [df["崗位名稱"].str.count(i) for i in target_job]index = np.array(index).sum(axis=0) > 0job_info = df[index]job_list = ["數(shù)據(jù)分析","數(shù)據(jù)統(tǒng)計","數(shù)據(jù)專員","數(shù)據(jù)挖掘","算法","大數(shù)據(jù)","開發(fā)工程師",            "運營","軟件工程","前端開發(fā)","深度學(xué)習(xí)","ai","數(shù)據(jù)庫","倉庫管理","數(shù)據(jù)產(chǎn)品",            "客服","java",".net","andrio","人工智能","c++","數(shù)據(jù)管理","測試","運維","數(shù)據(jù)工程師"]job_list = np.array(job_list)def Rename(x,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["崗位名稱"] = job_info["崗位名稱"].apply(lambda x:x.replace("數(shù)據(jù)專員","數(shù)據(jù)分析"))job_info["崗位名稱"] = job_info["崗位名稱"].apply(lambda x:x.replace("數(shù)據(jù)統(tǒng)計","數(shù)據(jù)分析"))#崗位薪資字段處理index1 = job_info["崗位薪資"].str[-1].isin(["年","月"])index2 = job_info["崗位薪資"].str[-3].isin(["萬","千"])job_info = job_info[index1 & index2]job_info["平均薪資"] = job_info["崗位薪資"].astype(str).apply(lambda x:np.array(x[:-3].split("-"),dtype=float))job_info["平均薪資"] = job_info["平均薪資"].apply(lambda x:np.mean(x))#統(tǒng)一工資單位job_info["單位"] = job_info["崗位薪資"].apply(lambda x:x[-3:])job_info["公司領(lǐng)域"].value_counts()def con_unit(x):    if x["單位"] == "萬/月":        z = x["平均薪資"]*10000    elif x["單位"] == "千/月":        z = x["平均薪資"]*1000    elif x["單位"] == "萬/年":        z = x["平均薪資"]/12*10000    return int(z)job_info["平均薪資"] = job_info.apply(con_unit,axis=1)job_info["單位"] = "元/月"#工作地點字段處理job_info["工作地點"] = job_info["工作地點"].apply(lambda x:x.split("-")[0])#公司領(lǐng)域字段處理job_info["公司領(lǐng)域"] = job_info["公司領(lǐng)域"].apply(lambda x:x.split("/")[0])#招聘人數(shù)字段處理job_info["招聘人數(shù)"] = job_info["招聘人數(shù)"].apply(lambda x:x.replace("若干","1").strip()[1:-1])#工作經(jīng)驗與學(xué)歷要求字段處理job_info["工作經(jīng)驗"] = job_info["工作經(jīng)驗"].apply(lambda x:x.replace("無需","1年以下").strip()[:-2])job_info["學(xué)歷需求"] = job_info["學(xué)歷需求"].apply(lambda x:x.split()[0])#公司規(guī)模字段處理job_info["公司規(guī)模"].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["公司規(guī)模"] = job_info["公司規(guī)模"].apply(func)#公司福利字段處理job_info["公司福利"] = job_info["公司福利"].apply(lambda x:str(x).split())#職位信息字段處理job_info["職位信息"] = job_info["職位信息"].apply(lambda x:x.split("職能類別")[0])with open(r"E:/C++/停用詞表.txt","r",encoding = "utf8") as f:    stopword = f.read()stopword = stopword.split()job_info["職位信息"] = job_info["職位信息"].apply(lambda x:x.lower()).apply(lambda x:"".join(x)).apply(lambda x:x.strip()).apply(jieba.lcut).apply(lambda x:[i for i in x if i not in stopword])cons = job_info["公司領(lǐng)域"].value_counts()industries = pd.DataFrame(cons.index,columns=["行業(yè)領(lǐng)域"])industry = pd.DataFrame(columns=["分詞明細(xì)","行業(yè)領(lǐng)域"])for i in industries["行業(yè)領(lǐng)域"]:    words = []    word = job_info["職位信息"][job_info["公司領(lǐng)域"] == i]    word.dropna(inplace=True)    [words.extend(str(z).strip("/"[]").split("/", /"")) for z in word]    df1 = pd.DataFrame({"分詞明細(xì)":words,                        "行業(yè)領(lǐng)域":i})    industry = industry.append(df1,ignore_index=True)industry = industry[industry["分詞明細(xì)"] != "http://n"]industry = industry[industry["分詞明細(xì)"] != ""]count = pd.DataFrame(industry["分詞明細(xì)"].value_counts())lst = list(count[count["分詞明細(xì)"] >=300].index)industry = industry[industry["分詞明細(xì)"].isin(lst)]#數(shù)據(jù)存儲industry.to_excel(r"E:/python爬蟲/數(shù)據(jù)預(yù)處理/詞云.xlsx")       job_info.to_excel(r"E:/python爬蟲/數(shù)據(jù)預(yù)處理/前程無憂(已清洗).xlsx")

?

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/121420.html

相關(guān)文章

  • 小李飛刀:ppppppython是需要好好學(xué)習(xí)的

    摘要:直接抄其中一份的結(jié)論吧各地區(qū)招聘公司數(shù)量和平均待遇??梢钥闯霾徽撌钦衅腹镜臄?shù)據(jù)還是平均待遇水平主要都是北上廣深杭州占優(yōu)勢。但事實證明,總是要有一些代價的。要學(xué)會看報錯信息。函數(shù)定義結(jié)束后需要按兩次回車重新回到提示符下。 又是寫在前面的亂七八糟 持續(xù)學(xué)習(xí)的第三天了,持續(xù)學(xué)習(xí)是一個不容易培養(yǎng)的好習(xí)慣,但是堅持就是勝利嘛~昨天因為一點點事情,所以沒能學(xué)習(xí)很長時間,今天要補(bǔ)回來。周末要搬家,...

    Simon 評論0 收藏0
  • node.js 爬取招聘信息分析各職業(yè)錢途(爬蟲+動態(tài)IP代理+數(shù)據(jù)視化分析

    摘要:成功爬取了拉鉤網(wǎng)上多個招聘崗位的具體信息后,數(shù)據(jù)可視化并得出分析結(jié)果如下從整體看,北上廣深杭這五個城市前端工程師招聘崗位,北京是遙遙領(lǐng)先,是深圳的兩倍,是廣州的三倍,其次到上海,深圳,杭州,廣州居末。 前前言 本文首發(fā)于 github blog 不想看爬蟲過程只想看職位錢途數(shù)據(jù)分析請看這里:前端招聘崗位分析C++招聘崗位分析JAVA招聘崗位分析PHP招聘崗位分析Python招聘崗位分析...

    546669204 評論0 收藏0
  • 拉勾數(shù)據(jù)崗位和熱門編程語言現(xiàn)狀分析

    摘要:另外數(shù)學(xué)成為了一個關(guān)鍵詞,編程語言主要是等,運營也出現(xiàn)在詞云中說明數(shù)據(jù)分析師也需要有運營能力。 功能點 爬取數(shù)據(jù) 所有公司數(shù)據(jù),名稱簡寫,城市,行業(yè),職位數(shù)量,人數(shù)范圍,標(biāo)簽,介紹,融資階段,平均工資 github2016年度最受歡迎編程語言相應(yīng)年數(shù)薪水,城市,學(xué)歷要求,公司融資階段,公司行業(yè) 大數(shù)據(jù)行業(yè)五大崗位相應(yīng)年數(shù)薪水,城市,學(xué)歷要求,公司融資階段,公司行業(yè),崗位要求 編程語...

    atinosun 評論0 收藏0
  • EDG奪冠,Python分析一波B站評論,總結(jié):EDG,nb

    摘要:填寫自己對應(yīng)的網(wǎng)頁更改相應(yīng)數(shù)據(jù)的編碼格式遇到請求掛起當(dāng)前任務(wù),等操作完成執(zhí)行之后的代碼,當(dāng)協(xié)程掛起時,事件循環(huán)可以去執(zhí)行其他任務(wù)。 前言 2012,一個卡牌,一個雷...

    seasonley 評論0 收藏0
  • 如何用Python進(jìn)行數(shù)據(jù)分析?

    摘要:編程基礎(chǔ)要學(xué)習(xí)如何用進(jìn)行數(shù)據(jù)分析,數(shù)據(jù)分析師建議第一步是要了解一些的編程基礎(chǔ),知道的數(shù)據(jù)結(jié)構(gòu),什么是向量列表數(shù)組字典等等了解的各種函數(shù)及模塊。數(shù)據(jù)分析師認(rèn)為數(shù)據(jù)分析有的工作都在處理數(shù)據(jù)。 showImg(https://segmentfault.com/img/bVbnbZo?w=1024&h=653); 本文為CDA數(shù)據(jù)分析研究院原創(chuàng)作品,轉(zhuǎn)載需授權(quán) 1.為什么選擇Python進(jìn)行數(shù)...

    lifefriend_007 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<