1. 程式人生 > >Python爬蟲——Python 崗位分析報告

Python爬蟲——Python 崗位分析報告

odin val arch 糗事百科 選項 ive 頁面數據 html 方便

前兩篇我們分別爬取了糗事百科和妹子圖網站,學習了 Requests, Beautiful Soup 的基本使用。不過前兩篇都是從靜態 HTML 頁面中來篩選出我們需要的信息。這一篇我們來學習下如何來獲取 Ajax 請求返回的結果。

歡迎關註公號【智能制造專欄】學習更多原創智能制造及編程知識。

Python 爬蟲入門(二)——爬取妹子圖
Python 爬蟲入門(一)——爬取糗百

本篇以拉勾網為例來說明一下如何獲取 Ajax 請求內容

本文目標

  1. 獲取 Ajax 請求,解析 JSON 中所需字段
  2. 數據保存到 Excel 中
  3. 數據保存到 MySQL, 方便分析

簡單分析

五個城市 Python 崗位平均薪資水平

技術分享圖片

Python 崗位要求學歷分布
技術分享圖片

Python 行業領域分布
技術分享圖片

Python 公司規模分布
技術分享圖片

查看頁面結構

我們輸入查詢條件以 Python 為例,其他條件默認不選,點擊查詢,就能看到所有 Python 的崗位了,然後我們打開控制臺,點擊網絡標簽可以看到如下請求:
技術分享圖片

從響應結果來看,這個請求正是我們需要的內容。後面我們直接請求這個地址就好了。從圖中可以看出 result 下面就是各個崗位信息。

到這裏我們知道了從哪裏請求數據,從哪裏獲取結果。但是 result 列表中只有第一頁 15 條數據,其他頁面數據怎麽獲取呢?

分析請求參數

我們點擊參數選項卡,如下:
技術分享圖片
發現提交了三個表單數據,很明顯看出來 kd 就是我們搜索的關鍵詞,pn 就是當前頁碼。first 默認就行了,不用管它。剩下的事情就是構造請求,來下載 30 個頁面的數據了。

構造請求,並解析數據

構造請求很簡單,我們還是用 requests 庫來搞定。首先我們構造出表單數據 data = {‘first‘: ‘true‘, ‘pn‘: page, ‘kd‘: lang_name} 之後用 requests 來請求url地址,解析得到的 Json 數據就算大功告成了。由於拉勾對爬蟲限制比較嚴格,我們需要把瀏覽器中 headers 字段全部加上,而且把爬蟲間隔調大一點,我後面設置的為 10-20s,然後就能正常獲取數據了。

import requests

def get_json(url, page, lang_name):
    headers = {
        'Host': 'www.lagou.com',
        'Connection': 'keep-alive',
        'Content-Length': '23',
        'Origin': 'https://www.lagou.com',
        'X-Anit-Forge-Code': '0',
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:61.0) Gecko/20100101 Firefox/61.0',
        'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
        'Accept': 'application/json, text/javascript, */*; q=0.01',
        'X-Requested-With': 'XMLHttpRequest',
        'X-Anit-Forge-Token': 'None',
        'Referer': 'https://www.lagou.com/jobs/list_python?city=%E5%85%A8%E5%9B%BD&cl=false&fromSearch=true&labelWords=&suginput=',
        'Accept-Encoding': 'gzip, deflate, br',
        'Accept-Language': 'en-US,en;q=0.9,zh-CN;q=0.8,zh;q=0.7'
    }
    data = {'first': 'false', 'pn': page, 'kd': lang_name}
    json = requests.post(url, data, headers=headers).json()
    list_con = json['content']['positionResult']['result']
    info_list = []
    for i in list_con:
        info = []
        info.append(i.get('companyShortName', '無'))
        info.append(i.get('companyFullName', '無'))
        info.append(i.get('industryField', '無'))
        info.append(i.get('companySize', '無'))
        info.append(i.get('salary', '無'))
        info.append(i.get('city', '無'))
        info.append(i.get('education', '無'))
        info_list.append(info)
    return info_list

獲取所有數據

了解了如何解析數據,剩下的就是連續請求所有頁面了,我們構造一個函數來請求所有 30 頁的數據。

def main():
    lang_name = 'python'
    wb = Workbook()
    conn = get_conn()
    for i in ['北京', '上海', '廣州', '深圳', '杭州']:
        page = 1
        ws1 = wb.active
        ws1.title = lang_name
        url = 'https://www.lagou.com/jobs/positionAjax.json?city={}&needAddtionalResult=false'.format(i)
        while page < 31:
            info = get_json(url, page, lang_name)
            page += 1
            import time
            a = random.randint(10, 20)
            time.sleep(a)
            for row in info:
                insert(conn, tuple(row))
                ws1.append(row)
    conn.close()
    wb.save('{}職位信息.xlsx'.format(lang_name))

if __name__ == '__main__':
    main()

完整代碼

import random
import time

import requests
from openpyxl import Workbook
import pymysql.cursors


def get_conn():
    '''建立數據庫連接'''
    conn = pymysql.connect(host='localhost',
                                user='root',
                                password='root',
                                db='python',
                                charset='utf8mb4',
                                cursorclass=pymysql.cursors.DictCursor)
    return conn


def insert(conn, info):
    '''數據寫入數據庫'''
    with conn.cursor() as cursor:
        sql = "INSERT INTO `python` (`shortname`, `fullname`, `industryfield`, `companySize`, `salary`, `city`, `education`) VALUES (%s, %s, %s, %s, %s, %s, %s)"
        cursor.execute(sql, info)
    conn.commit()


def get_json(url, page, lang_name):
    '''返回當前頁面的信息列表'''
    headers = {
        'Host': 'www.lagou.com',
        'Connection': 'keep-alive',
        'Content-Length': '23',
        'Origin': 'https://www.lagou.com',
        'X-Anit-Forge-Code': '0',
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:61.0) Gecko/20100101 Firefox/61.0',
        'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
        'Accept': 'application/json, text/javascript, */*; q=0.01',
        'X-Requested-With': 'XMLHttpRequest',
        'X-Anit-Forge-Token': 'None',
        'Referer': 'https://www.lagou.com/jobs/list_python?city=%E5%85%A8%E5%9B%BD&cl=false&fromSearch=true&labelWords=&suginput=',
        'Accept-Encoding': 'gzip, deflate, br',
        'Accept-Language': 'en-US,en;q=0.9,zh-CN;q=0.8,zh;q=0.7'
    }
    data = {'first': 'false', 'pn': page, 'kd': lang_name}
    json = requests.post(url, data, headers=headers).json()
    list_con = json['content']['positionResult']['result']
    info_list = []
    for i in list_con:
        info = []
        info.append(i.get('companyShortName', '無'))  # 公司名
        info.append(i.get('companyFullName', '無'))
        info.append(i.get('industryField', '無'))   # 行業領域
        info.append(i.get('companySize', '無'))  # 公司規模
        info.append(i.get('salary', '無'))   # 薪資
        info.append(i.get('city', '無'))
        info.append(i.get('education', '無'))   # 學歷
        info_list.append(info)
    return info_list   # 返回列表


def main():
    lang_name = 'python'
    wb = Workbook()  # 打開 excel 工作簿
    conn = get_conn()  # 建立數據庫連接  不存數據庫 註釋此行
    for i in ['北京', '上海', '廣州', '深圳', '杭州']:   # 五個城市
        page = 1
        ws1 = wb.active
        ws1.title = lang_name
        url = 'https://www.lagou.com/jobs/positionAjax.json?city={}&needAddtionalResult=false'.format(i)
        while page < 31:   # 每個城市30頁信息
            info = get_json(url, page, lang_name)
            page += 1
            time.sleep(random.randint(10, 20))
            for row in info:
                insert(conn, tuple(row))  # 插入數據庫,若不想存入 註釋此行
                ws1.append(row)
    conn.close()  # 關閉數據庫連接,不存數據庫 註釋此行
    wb.save('{}職位信息.xlsx'.format(lang_name))

if __name__ == '__main__':
    main()

GitHub 地址:https://github.com/injetlee/Python/tree/master/%E7%88%AC%E8%99%AB%E9%9B%86%E5%90%88

如果你想要爬蟲獲取的崗位信息,請關註公號【智能制造專欄】後臺留言發送 "python崗位"。
技術分享圖片

Python爬蟲——Python 崗位分析報告