爬蟲demo:52nlp上的招聘求職數據

Created on 2020-02-10

@author 假如我年華正好

目的:爬取 我愛自然語言 網站上的 招聘求職數據

環境:Python 3

爬蟲的兩大步驟

  1. 發送請求(request),獲取數據(response)

    向網址所在的服務器發送請求,即HTPP Request,服務器正常響應後會得到一個Response,其內容便是所要獲取的頁面內容。

    使用工具:requests 模塊

  2. 解析網頁內容

    使用工具:BeautifulSoup 模塊 —— HTML/XML解析器

分析目標網頁

本文欲爬取 我愛自然語言 網站上的 招聘求職數據,主要有兩個頁面:第一爲職位的列表頁;第二爲職位的詳情頁。示例如下:

在這裏插入圖片描述

在網頁上,單擊右鍵 —> 查看網頁源代碼,可以看到網頁的html源碼,我們通過 request 得到的內容就是這個。

Beautiful Soup 可以將我的得到的複雜HTML文檔,轉換成一個複雜的樹形結構,樹每個節點都是Python對象。所有對象可以歸納爲4種:Tag , NavigableString , BeautifulSoup ,Comment

下面對兩個頁面的源碼進行分析:

(1)頁面1:職位的列表頁

先找到我們需要的內容所在部分,即職位列表的源碼部分;

在這裏插入圖片描述

以其中一行爲例,分析源碼的結構:

在這裏插入圖片描述

分析發現:

  • 職位列表的行的 tag 的名字爲div,其 class 有兩種:class="row"calss="row-alt"
  • 職位類型(全職or實習)如何獲取:div —> span —> img[“alt”] (div tag 下的 span tag 下的 img tag 的 alt 屬性值)
  • 職位詳情頁鏈接如何獲取:div —> span —> a[“href”]
  • 職位發佈公司如何獲取:
  • 工作地點如何獲取:
  • 發佈時間如何獲取:div —> span.get_text()

下面用代碼演示如何獲取其中的內容:

import requests
from bs4 import BeautifulSoup


# 第一步:發送請求獲取,獲取數據
url = 'http://www.nlpjob.com/jobs'
resp = requests.get(url) # 發送請求
text = resp.content.decode("utf-8")  # 解碼
soup = BeautifulSoup(text, "html5lib")  # 實例化成 BeautifulSoup 對象
# 第二步:解析內容
# 獲取所有行的 tag,返回爲 bs 對象組成的列表 (對屬性的限制方式有以下兩種)
content = soup.find_all('div', class_="row-alt") 
content += soup.find_all('div', attrs={'class': "row"})
# 以其中一行爲例:
cont = content[0]
row_info = cont.find_all('span', class_="row-info")[0]
# 職位類型
job_type = cont.find_all('img')[0]['alt']
print(job_type)
# 詳情鏈接
href = row_info.find_all('a')[0]['href']
print(href)
# 內容標題/摘要
title = row_info.find_all('a')[0].get_text() #.get_text() = .strings
print(title)
# 公司&工作地點
la = row_info.get_text()
print(la)
# 發佈時間
time_posted = cont.find_all('span', class_="time-posted")[0].get_text()
print(time_posted)
Out[9]:全職
http://www.nlpjob.com/job/61399/%e5%9b%be%e6%a3%ae%e6%9c%aa%e6%9d%a5%e7%a7%91%e6%8a%80%e6%9c%89%e9%99%90%e5%85%ac%e5%8f%b8-at-%e5%9b%be%e6%a3%ae%e6%9c%aa%e6%9d%a5%e7%a7%91%e6%8a%80%e6%9c%89%e9%99%90%e5%85%ac%e5%8f%b8/
圖森未來科技有限公司

                        
                        圖森未來科技有限公司 at 圖森未來科技有限公司, 不限地址          
 2020-02-07
注意:列表頁的翻頁問題

在這裏插入圖片描述

發現不同頁只是url最後面的 ?p= 不一樣,所以本文采取:寫個循環,直接按規律修改 url ,循環爬取不同頁。

(2)頁面2:職位的詳情頁

詳情頁內容比較單純,只需爬取職位描述:

在這裏插入圖片描述

演示代碼如下:

detail_url = "http://www.nlpjob.com/job/61376/"
resp = requests.get(detail_url)
text = resp.content.decode("utf-8")
soup = BeautifulSoup(text, "html5lib")
job_description = soup.find('div', id='job-description')
job_description.get_text().replace('\t', '')

完整代碼

以下爲 demo 的完整代碼,其中對html源碼的解析的大邏輯前文已經介紹,部分細節不再詳述。

本文只爬取了2019年以後的職位信息(1-28頁),,

每一頁耗時約1分鐘,,

如下:

#!/usr/bin/python
# -*- coding: UTF-8 -*-

import pandas as pd
import re
import requests
from bs4 import BeautifulSoup
import time


def mul_delimiters_split(text, *dels):
    '''多個分隔符對字符串進行分割,並且分隔符可以是長短不一的'''
    delimiters = dels
    regexPattern = '|'.join(map(re.escape, delimiters)) # 'a|\\.\\.\\.|\\(C\\)'
    return re.split(regexPattern, text)


def parse_url_list(url):
    '''
    爬取並解析職位列表頁面數據
    '''
    resp = requests.get(url)
    text = resp.content.decode("utf-8")
    soup = BeautifulSoup(text, "html5lib")
    
    data = []
        
    content = soup.find_all('div', class_="row-alt")
    content += soup.find_all('div', attrs={'class': "row"})
    for cont in content:
        # 發佈時間
        time_posted = cont.find_all('span', class_="time-posted")[0].get_text()
        time_posted = time_posted.replace(' ', '', )
        
        row_info = cont.find_all('span', class_="row-info")[0]
        # 職位類型
        job_type = row_info.find_all('img')[0]['alt']
        # 詳情鏈接
        href = row_info.find_all('a')[0]['href']
        # 內容標題/摘要
        title = row_info.find_all('a')[0].get_text() #.get_text() = .strings
        # 公司&工作地點
        la = mul_delimiters_split(row_info.get_text(), ' at ', ' in ', ', ')[1:]
        
        # 儲存結果
        result = {'time_posted': time_posted,
                  'job_type': job_type,
                  'href': href,
                  'job_description': parse_url_detail(href),
                  'title': title,
                  'company': la[0],
                  'location': la[1].replace('\t', '')
                }
        data.append(result)
        
    return pd.DataFrame(data)


def parse_url_detail(detail_url):
    '''
    爬取並解析職位詳情頁數據
    '''
    resp = requests.get(detail_url)
    text = resp.content.decode("utf-8")
    soup = BeautifulSoup(text, "html5lib")
    
    job_description = soup.find('div', id='job-description')
    return job_description.get_text().replace('\t', '')


def main():
    urls = ["http://www.nlpjob.com/jobs/?p=" + str(i) for i in range(1, 28)]
    
    data = pd.DataFrame()
    for url in urls:
        s = time.time()
        print('正在爬取' + url + ' ...') 
        temp = parse_url_list(url)
        data = data.append(temp)
        print('完成!耗時 %s' %(time.time() - s))
           
    # 保存
    data.to_csv('../data/jobs.csv')    
    return data


if __name__ == '__main__':
    data = main()

最後的結果示例:
在這裏插入圖片描述

-------完--------

發佈了27 篇原創文章 · 獲贊 26 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章