成人无码视频,亚洲精品久久久久av无码,午夜精品久久久久久毛片,亚洲 中文字幕 日韩 无码

資訊專欄INFORMATION COLUMN

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

233jl / 2423人閱讀

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

目錄

一、項(xiàng)目背景

二、數(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ī)?!弊侄晤A(yù)處理

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

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

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

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

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

2、熱門城市用人需求Top15

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

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

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

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

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

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

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

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

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

五、源代碼

1、爬蟲源代碼

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


一、項(xiàng)目背景

????????隨著科技的不斷進(jìn)步與發(fā)展,數(shù)據(jù)呈現(xiàn)爆發(fā)式的增長,各行各業(yè)對于數(shù)據(jù)的依賴越來越強(qiáng),與數(shù)據(jù)打交道在所難免,而社會(huì)對于“數(shù)據(jù)”方面的人才需求也在不斷增大。因此了解當(dāng)下企業(yè)究竟需要招聘什么樣的人才?需要什么樣的技能?不管是對于在校生,還是對于求職者來說,都顯得十分必要。
? ? ? ? 對于一名小白來說,想要入門數(shù)據(jù)分析,首先要了解目前社會(huì)對于數(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)驗(yàn)、學(xué)歷需求、工作地點(diǎn)、招聘人數(shù)、發(fā)布時(shí)間、公司類型、公司規(guī)模、行業(yè)領(lǐng)域、福利待遇、職位信息;
  • 說明:在前程無憂招聘網(wǎng)站中,我們在搜索框中輸入“數(shù)據(jù)”兩個(gè)字進(jìn)行搜索發(fā)現(xiàn),共有2000個(gè)一級頁面,其中每個(gè)頁面包含50條崗位信息,因此總共有約100000條招聘信息。當(dāng)點(diǎn)擊一級頁面中每個(gè)崗位信息時(shí),頁面會(huì)跳轉(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),采用動(dòng)態(tài)渲染+限制ip訪問頻率等多層反爬,因此在獲取二級頁面鏈接時(shí)需借助json進(jìn)行解析,本文對于二級頁面崗位信息的獲取采用selenium模擬瀏覽器爬取,同時(shí)通過代理IP的方式,每隔一段時(shí)間換一次請求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)造自動(dòng)翻頁。

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è)置自動(dòng)翻頁       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鏈接時(shí)發(fā)現(xiàn)并非爬取的所有鏈接都是規(guī)范的,會(huì)存在少部分異常URL,這會(huì)對后續(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        工作地點(diǎn) = driver.find_elements_by_xpath("http://div[@class = "cn"]//p[@class = "msg ltype"]")[0].text.split("|")[0]        工作經(jīng)驗(yàn) = 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ā)布時(shí)間 = 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"        工作地點(diǎn) = "nan"        工作經(jīng)驗(yàn) = "nan"        學(xué)歷要求 = "nan"        招聘人數(shù) = "nan"        發(fā)布時(shí)間 = "nan"        print("信息提取異常,棄用")    finally:             info = {                "崗位名稱" : 崗位名稱,            "公司名稱" : 公司名稱,            "薪資水平" : 薪資水平,            "工作經(jīng)驗(yàn)" : 工作經(jīng)驗(yàn),            "學(xué)歷要求" : 學(xué)歷要求,            "工作地點(diǎn)" : 工作地點(diǎn),            "招聘人數(shù)" : 招聘人數(shù),            "發(fā)布時(shí)間" : 發(fā)布時(shí)間,            "公司類型" : 公司類型,            "公司規(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)。實(shí)際上,前程無憂招聘網(wǎng)站上與“數(shù)據(jù)”有關(guān)的只有幾百頁,而我們爬取了2000頁的所有數(shù)據(jù),因此在后面進(jìn)行數(shù)據(jù)處理時(shí)需要把無關(guān)的數(shù)據(jù)剔除掉。在爬取前根據(jù)對代碼的測試發(fā)現(xiàn),有些崗位字段在進(jìn)行爬取時(shí)會(huì)出現(xiàn)錯(cuò)位,從而導(dǎo)致數(shù)據(jù)存儲(chǔ)失敗,為了不影響后面代碼的執(zhí)行,這里設(shè)置了“try-except”進(jìn)行異常處理,同時(shí)使用while循環(huán)語句在服務(wù)器出現(xiàn)請求失敗時(shí)關(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)為一個(gè)記錄的公司名稱和崗位名稱一致時(shí),即可看作是重復(fù)值。因此利用drop_duplicates()函數(shù)剔除所有公司名稱和崗位名稱相同的記錄并保留第一個(gè)記錄。
  • 對于空值處理,只刪除所有字段信息都為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",然后對所有崗位做一個(gè)頻次統(tǒng)計(jì),統(tǒng)計(jì)結(jié)果發(fā)現(xiàn)“崗位名稱”字段很雜亂,且存在很多與“數(shù)據(jù)”無關(guān)的崗位,因此要對數(shù)據(jù)做一個(gè)篩選。

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)計(jì)判斷,如果包含任一關(guān)鍵詞則保留該記錄,如果不包含則刪除該字段。

#構(gòu)建目標(biāo)關(guān)鍵詞target_job = ["算法","開發(fā)","分析","工程師","數(shù)據(jù)","運(yùn)營","運(yùn)維","it","倉庫","統(tǒng)計(jì)"]#篩選目標(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)計(jì)情況,我們定義了目標(biāo)崗位列表job_list,用來替換統(tǒng)一相近的崗位名稱,之后,我們將“數(shù)據(jù)專員”、“數(shù)據(jù)統(tǒng)計(jì)”統(tǒng)一歸為“數(shù)據(jù)分析”。

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

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

?

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

? ? ? ? 對于“崗位薪資”字段的處理,重點(diǎn)在于對其單位格式轉(zhuǎn)換,在簡單觀察該字段后發(fā)現(xiàn),其存在“萬/年”、“萬/月”、“千/月”等不同單位,因此需要對其做一個(gè)統(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]#計(jì)算平均工資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)計(jì)預(yù)覽,之后做一個(gè)數(shù)據(jù)篩選剔除異常單位與空值記錄,再計(jì)算出每個(gè)字段的平均工資,接著定義一個(gè)函數(shù),將格式換算為“元/月”,得到最終的“平均薪資”字段。

4、“公司規(guī)?!弊侄晤A(yù)處理

? ? ? ? 對于“公司規(guī)?!弊侄蔚奶幚磔^簡單,只需要定義一個(gè)if條件語句將其格式做一個(gè)轉(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)行分類,求出每一個(gè)行業(yè)下各關(guān)鍵詞的詞頻統(tǒng)計(jì),以便于后期做詞云圖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ù)存儲(chǔ)industry.to_excel(r"E:/python爬蟲/數(shù)據(jù)處理/詞云.xlsx")   

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

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

? ? ? ? 我們針對清洗干凈后的數(shù)據(jù)另存為一個(gè)文檔,對源數(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個(gè),需求由高到低依次為:上海、深圳、廣州、北京、武漢、杭州、成都、南京、蘇州、無錫、西安、長沙、鄭州、重慶。其中上海用人需求高達(dá)10000人。

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

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

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

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

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

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

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

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

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

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

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

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

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        工作地點(diǎn) = driver.find_elements_by_xpath("http://div[@class = "cn"]//p[@class = "msg ltype"]")[0].text.split("|")[0]        工作經(jīng)驗(yàn) = 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ā)布時(shí)間 = 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"        工作地點(diǎn) = "nan"        工作經(jīng)驗(yàn) = "nan"        學(xué)歷要求 = "nan"        招聘人數(shù) = "nan"        發(fā)布時(shí)間 = "nan"        print("信息提取異常,棄用")    finally:             info = {                "崗位名稱" : 崗位名稱,            "公司名稱" : 公司名稱,            "薪資水平" : 薪資水平,            "工作經(jīng)驗(yàn)" : 工作經(jīng)驗(yàn),            "學(xué)歷要求" : 學(xué)歷要求,            "工作地點(diǎn)" : 工作地點(diǎn),            "招聘人數(shù)" : 招聘人數(shù),            "發(fā)布時(shí)間" : 發(fā)布時(shí)間,            "公司類型" : 公司類型,            "公司規(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ù)","運(yùn)營","運(yùn)維","it","倉庫","統(tǒng)計(jì)"]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)計(jì)","數(shù)據(jù)專員","數(shù)據(jù)挖掘","算法","大數(shù)據(jù)","開發(fā)工程師",            "運(yùn)營","軟件工程","前端開發(fā)","深度學(xué)習(xí)","ai","數(shù)據(jù)庫","倉庫管理","數(shù)據(jù)產(chǎn)品",            "客服","java",".net","andrio","人工智能","c++","數(shù)據(jù)管理","測試","運(yùn)維","數(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)計(jì)","數(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["單位"] = "元/月"#工作地點(diǎn)字段處理job_info["工作地點(diǎn)"] = job_info["工作地點(diǎn)"].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)驗(yàn)與學(xué)歷要求字段處理job_info["工作經(jīng)驗(yàn)"] = job_info["工作經(jīng)驗(yàn)"].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ù)存儲(chǔ)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://m.hztianpu.com/yun/121420.html

相關(guān)文章

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

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

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

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

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

    摘要:另外數(shù)學(xué)成為了一個(gè)關(guān)鍵詞,編程語言主要是等,運(yùn)營也出現(xiàn)在詞云中說明數(shù)據(jù)分析師也需要有運(yùn)營能力。 功能點(diǎn) 爬取數(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é)程掛起時(shí),事件循環(huán)可以去執(zhí)行其他任務(wù)。 前言 2012,一個(gè)卡牌,一個(gè)雷...

    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元查看
<