亚洲国产第一_开心网五月色综合亚洲_日本一级特黄特色大片免费观看_久久久久久久久久免观看

Hello! 歡迎來到小浪云!


Python爬蟲之六:智聯(lián)招聘進階版


avatar
小浪云 2025-05-14 12

運行平臺: windows python版本: python3.6 idesublime text 其他工具chrome瀏覽器

0、寫在前面的話

本文是基于基礎(chǔ)版上做的修改,如果沒有閱讀基礎(chǔ)版,請移步 Python爬蟲之五:抓取智聯(lián)招聘基礎(chǔ)版

在基礎(chǔ)版中,構(gòu)造url時使用了urllib庫的urlencode函數(shù):

代碼語言:JavaScript代碼運行次數(shù):0運行復(fù)制

 url = 'https://sou.zhaopin.com/jobs/searchresult.ashx?' + urlencode(paras)    try:        # 獲取網(wǎng)頁內(nèi)容,返回html數(shù)據(jù)        response = requests.get(url, headers=headers)    ...

其實用reuqests庫可以完成此工作,本例將該部分改為:

代碼語言:javascript代碼運行次數(shù):0運行復(fù)制

 url = 'https://sou.zhaopin.com/jobs/searchresult.ashx?'    try:        # 獲取網(wǎng)頁內(nèi)容,返回html數(shù)據(jù)        response = requests.get(url, params=paras, headers=headers)    ...

1、找到職位鏈接

為了得到更加詳細的職位信息,我們要找到職位鏈接,在新的頁面中尋找數(shù)據(jù)。上篇文章中我們沒有解析職位鏈接,那再來找一下吧:

立即學(xué)習(xí)Python免費學(xué)習(xí)筆記(深入)”;

Python爬蟲之六:智聯(lián)招聘進階版

修改一下正則表達式

代碼語言:javascript代碼運行次數(shù):0運行復(fù)制

# 正則表達式進行解析    pattern = re.compile('<td class="zwmc" . target="_blank">(.*?).*?' # 匹配職位詳情地址和職位名稱        '</td><td class="gsmc">.*? target="_blank"&gt;(.*?).*?'                             # 匹配公司名稱        '</td><td class="zwyx">(.*?)</td>', re.S)                                            # 匹配月薪          # 匹配所有符合條件的內(nèi)容    items = re.findall(pattern, html)   

2、求工資平均值

工資有兩種形式xxxx-yyyy或者面議,此處取第一種形式的平均值作為分析標(biāo)準(zhǔn),雖有偏差但是也差不多,這是求職中最重要的一項指標(biāo)。

代碼語言:javascript代碼運行次數(shù):0運行復(fù)制

for item in items:    salary_avarage = 0    temp = item[3]    if temp != '面議':        idx = temp.find('-')        # 求平均工資        salary_avarage = (int(temp[0:idx]) + int(temp[idx+1:]))//2

3、解析職位詳細信息3.1 網(wǎng)頁解析

第一步已經(jīng)將職位地址找到,在瀏覽器打開之后我們要找到如下幾項數(shù)據(jù):

Python爬蟲之六:智聯(lián)招聘進階版

在開發(fā)者工具中查找這幾項數(shù)據(jù),如下圖所示:

Python爬蟲之六:智聯(lián)招聘進階版

HTML結(jié)構(gòu)如下所示:

代碼語言:javascript代碼運行次數(shù):0運行復(fù)制

# 數(shù)據(jù)HTML結(jié)構(gòu)|------<div class="terminalpage clearfix">==&gt;|------<div class="terminalpage-left">==&gt;==&gt;|------<ul class="terminal-ul clearfix">==&gt;==&gt;==&gt;|------<li> <span>工作經(jīng)驗:</span><strong>3-5年</strong>==&gt;==&gt;==&gt;|------</li> <li> <span>最低學(xué)歷:</span><strong>本科</strong>==&gt;==&gt;|------<div class="terminalpage-main clearfix">==&gt;==&gt;==&gt;|------<div class="tab-cont-box">==&gt;==&gt;==&gt;==&gt;|------<div class="tab-inner-cont">==&gt;==&gt;==&gt;==&gt;==&gt;|------<p>工作職責(zé):</p>==&gt;==&gt;==&gt;==&gt;==&gt;|------<p>********</p>==&gt;==&gt;==&gt;==&gt;==&gt;|------<p>********</p>    # 工作職責(zé)詳情==&gt;|------<div class="terminalpage-right">    ==&gt;==&gt;|------<div class="company-box">==&gt;==&gt;==&gt;|------<ul class="terminal-ul clearfix terminal-company mt20">==&gt;==&gt;==&gt;==&gt;|------<li> <span>公司規(guī)模:</span><strong>100-499人</strong>3.2 代碼實現(xiàn)<p>為了學(xué)習(xí)一下beautifulsoup庫的使用,我們不再使用正則表達式解析,而是BeautifulSoup庫解析HTML標(biāo)簽來獲得我們想要得到的內(nèi)容。</p> <p>解析庫的安裝:pip install beautifulsoup4</p> <p>下面介紹一下本例中使用到的功能:</p>庫的引入:from bs4 import BeautifulSoup數(shù)據(jù)引入:soup = BeautifulSoup(html, 'html.parser') ,其中html是我們要解析的html源碼,html.parser指定HTML的解析器為Python<a style="color:#f60; text-decoration:underline;" title="標(biāo)準(zhǔn)庫" href="https://www.php.cn/zt/74427.html" target="_blank">標(biāo)準(zhǔn)庫</a>。查找標(biāo)簽:find(name,attrs,recursive,text,**kwargs),find返回的匹配結(jié)果的第一個元素查找所有標(biāo)簽:find_all(name,attrs,recursive,text,**kwargs)可以根據(jù)標(biāo)簽名,屬性,內(nèi)容查找文檔,返回找到的所有元素獲取內(nèi)容:get_text()就可以獲取文本內(nèi)容獲取子標(biāo)簽:soup.p這種方式就可以獲取到soup下的第一個p標(biāo)簽代碼語言:javascript<i class="icon-code"></i>代碼運行次數(shù):<!-- -->0<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewbox="0 0 16 16" fill="none"><path d="M6.66666 10.9999L10.6667 7.99992L6.66666 4.99992V10.9999ZM7.99999 1.33325C4.31999 1.33325 1.33333 4.31992 1.33333 7.99992C1.33333 11.6799 4.31999 14.6666 7.99999 14.6666C11.68 14.6666 14.6667 11.6799 14.6667 7.99992C14.6667 4.31992 11.68 1.33325 7.99999 1.33325ZM7.99999 13.3333C5.05999 13.3333 2.66666 10.9399 2.66666 7.99992C2.66666 5.05992 5.05999 2.66659 7.99999 2.66659C10.94 2.66659 13.3333 5.05992 13.3333 7.99992C13.3333 10.9399 10.94 13.3333 7.99999 13.3333Z" fill="currentcolor"></path></svg>運行<svg width="16" height="16" viewbox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M4.5 15.5V3.5H14.5V15.5H4.5ZM12.5 5.5H6.5V13.5H12.5V5.5ZM9.5 2.5H3.5V12.5H1.5V0.5H11.5V2.5H9.5Z" fill="currentcolor"></path></svg>復(fù)制<pre class="prism-token token line-numbers javascript">def get_job_detail(html):    requirement = ''    # 使用BeautifulSoup進行數(shù)據(jù)篩選    soup = BeautifulSoup(html, 'html.parser')    # 找到
    標(biāo)簽 for ul in soup.find_all(‘ul’, class_=’terminal-ul clearfix’): # 該標(biāo)簽共有8個子標(biāo)簽,分別為: # 職位月薪|工作地點|發(fā)布日期|工作性質(zhì)|工作經(jīng)驗|最低學(xué)歷|招聘人數(shù)|職位類別 lis = ul.find_all(‘strong’) # 工作經(jīng)驗 years = lis[4].get_text() # 最低學(xué)歷 education = lis[5].get_text() # 篩選任職要求 for terminalpage in soup.find_all(‘div’, class_=’terminalpage-main clearfix’): for box in terminalpage.find_all(‘div’, class_=’tab-cont-box’): cont = box.find_all(‘div’, class_=’tab-inner-cont’)[0] ps = cont.find_all(‘p’) # “立即申請”按鈕也是個p標(biāo)簽,將其排除 for i in range(len(ps) – 1): requirement += ps[i].get_text().replace(“n”, “”).strip() # 去掉換行符和空格 # 篩選公司規(guī)模,該標(biāo)簽內(nèi)有四個或五個

  • 標(biāo)簽,但是第一個就是公司規(guī)模 scale = soup.find(class_=’terminal-ul clearfix terminal-company mt20′).find_all(‘li’)[0].strong.get_text() return {‘years’: years, ‘education’: education, ‘requirement’: requirement, ‘scale’: scale}

    本次我們將職位描述寫入txt文件,其余信息寫入csv文件。

    csv文件采用逐行寫入的方式這樣也可以省點內(nèi)存,修改write_csv_rows函數(shù):

    代碼語言:javascript代碼運行次數(shù):0運行復(fù)制

    def write_csv_rows(path, headers, rows):    '''    寫入行    '''    with open(path, 'a', encoding='gb18030', newline='') as f:        f_csv = csv.DictWriter(f, headers)        # 如果寫入數(shù)據(jù)為字典,則寫入一行,否則寫入多行        if type(rows) == type({}):            f_csv.writerow(rows)        else:            f_csv.writerows(rows)

    添加寫txt文件函數(shù):

    代碼語言:javascript代碼運行次數(shù):0運行復(fù)制

    def write_txt_file(path, txt):    '''    寫入txt文本    '''    with open(path, 'a', encoding='gb18030', newline='') as f:        f.write(txt)

    我們最重要對職位描述的內(nèi)容進行詞頻統(tǒng)計,一些標(biāo)點符號等會影響統(tǒng)計,使用正則表達式將其剔除:

    代碼語言:javascript代碼運行次數(shù):0運行復(fù)制

    # 對數(shù)據(jù)進行清洗,將標(biāo)點符號等對詞頻統(tǒng)計造成影響的因素剔除pattern = re.compile(r'[一-龥]+')filterdata = re.findall(pattern, job_detail.get('requirement'))write_txt_file(txt_filename, ''.join(filterdata))

    至此,職位詳細信息的獲取及保存的工作已經(jīng)完成,來看一下此時的main函數(shù):

    代碼語言:javascript代碼運行次數(shù):0運行復(fù)制

    def main(city, keyword, region, pages):    '''    主函數(shù)    '''    csv_filename = 'zl_' + city + '_' + keyword + '.csv'    txt_filename = 'zl_' + city + '_' + keyword + '.txt'    headers = ['job', 'years', 'education', 'salary', 'company', 'scale', 'job_url']    write_csv_headers(csv_filename, headers)    for i in range(pages):        '''        獲取該頁中所有職位信息,寫入csv文件        '''        job_dict = {}        html = get_one_page(city, keyword, region, i)        items = parse_one_page(html)        for item in items:            html = get_detail_page(item.get('job_url'))            job_detail = get_job_detail(html)            job_dict['job'] = item.get('job')            job_dict['years'] = job_detail.get('years')            job_dict['education'] = job_detail.get('education')            job_dict['salary'] = item.get('salary')            job_dict['company'] = item.get('company')            job_dict['scale'] = job_detail.get('scale')            job_dict['job_url'] = item.get('job_url')            # 對數(shù)據(jù)進行清洗,將標(biāo)點符號等對詞頻統(tǒng)計造成影響的因素剔除            pattern = re.compile(r'[一-龥]+')            filterdata = re.findall(pattern, job_detail.get('requirement'))            write_txt_file(txt_filename, ''.join(filterdata))            write_csv_rows(csv_filename, headers, job_dict)

    4、數(shù)據(jù)分析

    本節(jié)內(nèi)容為此版本的重點。

    4.1 工資統(tǒng)計

    我們對各個階段工資的占比進行統(tǒng)計,分析該行業(yè)的薪資分布水平。前面我們已經(jīng)把數(shù)據(jù)保存到csv文件里了,接下來要讀取salary列:

    代碼語言:javascript代碼運行次數(shù):0運行復(fù)制

    def read_csv_column(path, column):    '''    讀取一列    '''    with open(path, 'r', encoding='gb18030', newline='') as f:        reader = csv.reader(f)        return [row[column] for row in reader]# main函數(shù)里添加print(read_csv_column(csv_filename, 3))#下面為打印結(jié)果['salary', '7000', '5000', '25000', '12500', '25000', '20000', '32500', '20000', '15000', '9000', '5000', '5000', '12500', '24000', '15000', '18000', '25000', '20000', '0', '20000', '12500', '17500', '17500', '20000', '11500', '25000', '12500', '17500', '25000', '22500', '22500', '25000', '17500', '7000', '25000', '3000', '22500', '15000', '25000', '20000', '22500', '15000', '15000', '25000', '17500', '22500', '10500', '20000', '17500', '22500', '17500', '25000', '20000', '11500', '11250', '12500', '14000', '12500', '17500', '15000']

    從結(jié)果可以看出,除了第一項,其他的都為平均工資,但是此時的工資為字符串,為了方便統(tǒng)計,我們將其轉(zhuǎn)換成整形:

    代碼語言:javascript代碼運行次數(shù):0運行復(fù)制

    salaries = []sal = read_csv_column(csv_filename, 3)    # 撇除第一項,并轉(zhuǎn)換成整形,生成新的列表    for i in range(len(sal) - 1):        # 工資為'0'的表示招聘上寫的是'面議',不做統(tǒng)計        if not sal[i] == '0':            salaries.append(int(sal[i + 1]))    print(salaries)# 下面為打印結(jié)果[7000, 5000, 25000, 12500, 25000, 20000, 32500, 20000, 15000, 9000, 5000, 5000, 12500, 24000, 15000, 18000, 25000, 20000, 0, 20000, 12500, 20000, 11500, 17500, 25000, 12500, 17500, 25000, 25000, 22500, 22500, 17500, 17500, 7000, 25000, 3000, 22500, 15000, 25000, 20000, 22500, 15000, 22500, 10500, 20000, 15000, 17500, 17500, 25000, 17500, 22500, 25000, 12500, 20000, 11250, 11500, 14000, 12500, 15000, 17500]

    我們用直方圖進行展示:

    代碼語言:javascript代碼運行次數(shù):0運行復(fù)制

    plt.hist(salaries, bins=10 ,)plt.show()

    生成效果圖如下:

    Python爬蟲之六:智聯(lián)招聘進階版

    從圖中可以看出工資分布的情況,這樣在你找工作時可以做一個參考。

    4.2 職位描述詞頻統(tǒng)計

    對職位描述詞頻統(tǒng)計的意義是可以了解該職位對技能的基本要求,如果正在找工作,可以估計一下自己的要求是否符合該職位;如果想要一年后換工作,那么也可以提前做好準(zhǔn)備,迎接新的挑戰(zhàn)。

    詞頻統(tǒng)計用到了 jieba、numpy、pandasscipy庫。如果電腦上沒有這兩個庫,執(zhí)行安裝指令:

    pip install jiebapip install pandaspip install numpypip install scipy4.2.1 讀取txt文件

    前面已經(jīng)將職位描述保存到txt文件里了,現(xiàn)在我們將其讀出:

    代碼語言:javascript代碼運行次數(shù):0運行復(fù)制

    def read_txt_file(path):    '''    讀取txt文本    '''    with open(path, 'r', encoding='gb18030', newline='') as f:        return f.read()

    簡單測試一下:

    代碼語言:javascript代碼運行次數(shù):0運行復(fù)制

    import jiebaimport pandas as pdcontent = read_txt_file(txt_filename)segment = jieba.lcut(content)words_df=pd.DataFrame({'segment':segment})print(words_df)# 輸出結(jié)果如下:      segment0        崗位職責(zé)1          參與2          公司3        軟件產(chǎn)品4          后臺5          研發(fā)6           和7          維護8          工作9          參與10        建筑物11         聯(lián)網(wǎng)12       數(shù)據(jù)分析13         算法14          的15         設(shè)計16          和17         開發(fā)18          可19         獨立20         完成21         業(yè)務(wù)22         算法23         模塊...            ...

    從結(jié)果可以看出:“崗位職責(zé)”、“參與”、“公司”、軟件產(chǎn)品“、”的“、”和“等單詞并沒有實際意義,所以我們要將他們從表中刪除。

    4.2.2 stop word

    下面引入一個概念:stop word, 在網(wǎng)站里面存在大量的常用詞比如:“在”、“里面”、“也”、“的”、“它”、“為”這些詞都是停止詞。這些詞因為使用頻率過高,幾乎每個網(wǎng)頁上都存在,所以搜索引擎開發(fā)人員都將這一類詞語全部忽略掉。如果我們的網(wǎng)站上存在大量這樣的詞語,那么相當(dāng)于浪費了很多資源。

    百度搜索stpowords.txt進行下載,放到py文件同級目錄。接下來測試一下:

    代碼語言:javascript代碼運行次數(shù):0運行復(fù)制

    content = read_txt_file(txt_filename)segment = jieba.lcut(content)words_df=pd.DataFrame({'segment':segment})stopwords=pd.read_csv("stopwords.txt",index_col=False,quoting=3,sep=" ",names=['stopword'],encoding='utf-8')words_df=words_df[~words_df.segment.isin(stopwords.stopword)]print(words_df)# 以下為輸出結(jié)果0        崗位職責(zé)1          參與2          公司3        軟件產(chǎn)品4          后臺5          研發(fā)7          維護8          工作9          參與10        建筑物11         聯(lián)網(wǎng)12       數(shù)據(jù)分析13         算法15         設(shè)計17         開發(fā)19         獨立21         業(yè)務(wù)22         算法23         模塊24         開發(fā)28         產(chǎn)品29         目標(biāo)31         改進32         創(chuàng)新33         任職35         熟練38         開發(fā)39         經(jīng)驗40         優(yōu)先41         熟悉...       ...

    從結(jié)果看出,那些常用的stop word比如:“的”、“和”、“可”等已經(jīng)被剔除了,但是還有一些詞如“崗位職責(zé)”、“參與”等也沒有實際意義,如果對詞頻統(tǒng)計不產(chǎn)生影響,那么就無所謂,在后面統(tǒng)計時再決定是否對其剔除。

    4.2.3 詞頻統(tǒng)計

    重頭戲來了,詞頻統(tǒng)計使用numpy:

    代碼語言:javascript代碼運行次數(shù):0運行復(fù)制

    import numpywords_stat = words_df.groupby(by=['segment'])['segment'].agg({"計數(shù)":numpy.size})    words_stat = words_stat.reset_index().sort_values(by=["計數(shù)"],ascending=False)    print(words_stat)# 以下是爬取全部“北京市海淀區(qū)Python工程師”職位的運行結(jié)果:    segment   計數(shù)362      開發(fā)  505590      熟悉  409701      經(jīng)驗  281325      工作  209820      負責(zé)  171741      能力  169793      設(shè)計  16182       優(yōu)先  160409      技術(shù)  157621      相關(guān)  145322    崗位職責(zé)  127683      系統(tǒng)  12664       產(chǎn)品  124904      項目  123671      算法  10778       任職  107532      框架  107591      熟練  104

    可以看出,某些詞語還是影響了統(tǒng)計結(jié)果,我將以下stop word加入stopword.txt中:

    代碼語言:javascript代碼運行次數(shù):0運行復(fù)制

    開發(fā)、熟悉、熟練、精通、經(jīng)驗、工作、負責(zé)、能力、有限、相關(guān)、崗位職責(zé)、任職、語言、平臺、參與、優(yōu)先、技術(shù)、學(xué)習(xí)、產(chǎn)品、公司、熟練掌握、以上學(xué)歷

    最后運行結(jié)果如下:

    代碼語言:javascript代碼運行次數(shù):0運行復(fù)制

    775      設(shè)計  136667      系統(tǒng)  109884      項目  105578      熟練   95520      框架   92656      算法   90143      分析   9080       優(yōu)化   77471     數(shù)據(jù)庫   75693      維護   66235      團隊   6572       代碼   61478      文檔   60879      需求   58766     計算機   56698      編程   56616      研發(fā)   49540      溝通   49527      模塊   49379      性能   46695      編寫   45475    數(shù)據(jù)結(jié)構(gòu)   44

    這樣基本上就是對技能的一些要求了,你也可以根據(jù)自己的需求再去修改stopword.txt已達到更加完美的效果。

    4.2.4 詞頻可視化:詞云

    詞頻統(tǒng)計雖然出來了,可以看出排名,但是不完美,接下來我們將它可視化。使用到wordcloud庫,詳細介紹見 github ,使用pip install wordcloud進行安裝。

    代碼語言:javascript代碼運行次數(shù):0運行復(fù)制

    from scipy.misc import imreadfrom wordcloud import WordCloud, ImageColorGenerator    # 設(shè)置詞云屬性    color_mask = imread('background.jfif')    wordcloud = WordCloud(font_path="simhei.ttf",   # 設(shè)置字體可以顯示中文                    background_color="white",       # 背景顏色                    max_words=100,                  # 詞云顯示的最大詞數(shù)                    mask=color_mask,                # 設(shè)置背景圖片                    max_font_size=100,              # 字體最大值                    random_state=42,                    width=1000, height=860, margin=2,# 設(shè)置圖片默認的大小,但是如果使用背景圖片的話,                                                   # 那么保存的圖片大小將會按照其大小保存,margin為詞語邊緣距離                    )    # 生成詞云, 可以用generate輸入全部文本,也可以我們計算好詞頻后使用generate_from_frequencies函數(shù)    word_frequence = {x[0]:x[1]for x in words_stat.head(100).values}    word_frequence_dict = {}    for key in word_frequence:        word_frequence_dict[key] = word_frequence[key]    wordcloud.generate_from_frequencies(word_frequence_dict)    # 從背景圖片生成顏色值      image_colors = ImageColorGenerator(color_mask)     # 重新上色    wordcloud.recolor(color_func=image_colors)    # 保存圖片    wordcloud.to_file('output.png')    plt.imshow(wordcloud)    plt.axis("off")    plt.show()

    運行效果圖如下(左圖為原圖,右圖為生成的圖片):

    Python爬蟲之六:智聯(lián)招聘進階版

    至此,詞頻統(tǒng)計及其可視化完成。

    5、其他想法

    本例中進行了兩種數(shù)據(jù)分析,雖為進階版,但是還是有很多可以繼續(xù)發(fā)揮的地方:

    分析工作年限和工資的關(guān)系并展示、預(yù)測統(tǒng)計不同工作崗位的薪資差別利用線程或多進程提升效率

    推薦閱讀:

    Python爬蟲:十幾行代碼下載王者榮耀所有皮膚Python爬蟲之二:自制簡易詞典Python爬蟲之三:抓取貓眼電影TOP100Python爬蟲之四:今日頭條街拍美圖Python爬蟲之五:抓取智聯(lián)招聘基礎(chǔ)版

相關(guān)閱讀