爬蟲練習二:爬取智聯招聘職位信息

1. 簡介

由於想要找到一個數據分析的工做,可以瞭解到市面上現有的職位招聘信息也會對找工做有所幫助。python

今天就來爬取一下智聯招聘上數據分析師的招聘信息,並存入本地的MySQL。mysql

 

2. 頁面分析

2.1 找到數據來源

打開智聯招聘首頁,選擇數據分析師職位,跳轉進入數據分析師的詳情頁面。咱們須要抓取的數據都呈如今這裏。sql

既然咱們想要的數據都在這個頁面上,那麼就對頁面分析一下,這些數據都是用什麼方式傳輸的。數據庫

首先右鍵查看網頁源代碼,發現職位信息並不在源代碼裏面。也就是說,職位信息是經過其餘來源加載的,並非直接寫入這個網頁的代碼裏。json

右鍵檢查,找到network一覽進行查看,發現職位信息實際上是來源於接口返回的一個json格式的數據。因此咱們要抓取的數據就來源於這個接口:api

 

2.2 分析url構成

由2.1,咱們已經找到數據來源的url爲 dom

https://fe-api.zhaopin.com/c/i/sou?pageSize=90&workExperience=-1&education=-1&companyType=-1&employmentType=-1&jobWelfareTag=-1&kw=%E6%95%B0%E6%8D%AE%E5%88%86%E6%9E%90%E5%B8%88&kt=3&_v=0.55861702&x-zp-page-request-id=112663d962234d3e8ca52b6e9d5ab4ea-1545222165002-62086url

這個url中包含了不少參數,分別對應在職位搜索時加入的條件:spa

pageSize:指每一頁顯示的職位數量,也就是經過url一次取多少數設計

cityId:指職位的城市劃分,489表明全國

workExperience:指職位要求的工做經驗

education:職位要求的學歷水平

companyType:公司的經營類別

employmentType:職位的性質,如實習/全職/兼職

jobWelfareTag:福利

kw:搜索關鍵字,若是關鍵字包含漢字,則進行url轉碼。如:此處,數據分析師轉碼爲%E6%95%B0%E6%8D%AE%E5%88%86%E6%9E%90%E5%B8%88

kt/_v/x-zp-request-id:暫時沒有弄明白具體是指什麼

 

上面的url只是搜索結果第一頁對應的來源,而咱們的搜索結果實際上是有不少頁進行展現的。

經過一樣的方式,能夠拿到搜索結果接下來幾頁對應的url。

以第二頁對應的url爲例:

https://fe-api.zhaopin.com/c/i/sou?start=90&pageSize=90&workExperience=-1&education=-1&companyType=-1&employmentType=-1&jobWelfareTag=-1&kw=%E6%95%B0%E6%8D%AE%E5%88%86%E6%9E%90%E5%B8%88&kt=3&_v=0.55861702&x-zp-page-request-id=112663d962234d3e8ca52b6e9d5ab4ea-1545222165002-62086

對比以後,發現:區別之處僅僅在於第二頁對應的url加入了一個start參數。

start=90,即爲第二頁的搜索結果。結合pageSize參數,每一頁展現90條職位信息。也就是說,start=90表示第二頁,start=180表示第三頁......

咱們就知道了如何去獲得每一頁搜索結果對應的數據來源了。

 

 

3. 抓取數據

3.1 設計數據獲取流程

既然咱們已經發現了,每一頁的職位信息都來自於訪問接口後返回的json格式的數據,咱們就能夠直接訪問接口而後讀取json就能夠獲得想要的職位信息了。

步驟以下:

1) 設定關鍵字訪問接口,得到包含職位信息的json數據

2) 從返回的json中提取須要的數據,存入本地MySQL中

 

3.2 代碼實現

由於這些職位數據是沒有通過登錄就能夠獲取的,並且在請求頭中並無發現什麼特別的信息。嘗試後發現,智聯招聘對傳輸職位信息的這個接口沒有作什麼反爬限制,直接使用urllib包的urlopen()方法就能夠得到數據。

import pymysql
import urllib
import json
import time
import random

# 在sql中建立表
def create_table_mysql():
    db = pymysql.connect(host='localhost', user='root', password='mysqlkey', db='test_db', port=3306)

    # 建立遊標對象cursor
    cursor = db.cursor()
    # 執行SQL,若是表存在就刪除
    cursor.execute('DROP TABLE IF EXISTS zlzp_sjfx')
    # 建立表
    create_table_sql = """
            CREATE TABLE zlzp_sjfx(
                job_number CHAR(100) COMMENT '記錄編號',
                job_type_big_num CHAR(100) COMMENT '職業大分類編號',
                job_type_big_name CHAR(100) COMMENT '職業大分類名稱',
                job_type_medium_num CHAR(100) COMMENT '職業細分類編號',
                job_type_medium_name CHAR(100) COMMENT '職業細分類名稱',
                company_num CHAR(100) COMMENT '公司編號',
                company_url CHAR(200) COMMENT '公司對應url',
                company_name CHAR(100) COMMENT '公司名稱',
                company_size_num CHAR(100) COMMENT '公司規模編號',
                company_size CHAR(100) COMMENT '公司規模',
                company_type_num CHAR(100) COMMENT '公司類型編號',
                company_type CHAR(100) COMMENT '公司類型',
                job_url CHAR(200) COMMENT '職位對應url',
                working_exp_num CHAR(100) COMMENT '工做經驗編號',
                working_exp CHAR(100) COMMENT '工做經驗',
                edu_level_num CHAR(100) COMMENT '教育水平編號',
                edu_level CHAR(100) COMMENT '教育水平',
                job_salary CHAR(100) COMMENT '工資',
                job_type CHAR(100) COMMENT '工做類型',
                job_name CHAR(100) COMMENT '工做類型',
                job_location_lat CHAR(100) COMMENT '經度',
                job_location_lon CHAR(100) COMMENT '緯度',
                job_city CHAR(100) COMMENT '工做城市',
                job_updatetime CHAR(100) COMMENT '更新時間',
                job_createtime CHAR(100) COMMENT '建立時間',
                job_endtime CHAR(100) COMMENT '結束時間',
                job_welfare CHAR(100) COMMENT '工做福利'
            )"""
     
    try:
        # 建立表
        cursor.execute(create_table_sql)
        # 提交執行
        db.commit()
        print('table zlzp_sjfx create done')
    except:
        # 回滾
        db.rollback()
        print('table zlzp_sjfx create not done')
        
    return db, cursor

db, cursor = create_table_mysql()
time_0 = time.time()

for i in range(500):
    url = 'https://fe-api.zhaopin.com/c/i/sou?start={}&pageSize=90&cityId=489&workExperience=-1&education=-1&companyType=-1&employmentType=-1&jobWelfareTag=-1&kw=%E6%95%B0%E6%8D%AE%E5%88%86%E6%9E%90%E5%B8%88&kt=3&_v=0.89067574&x-zp-page-request-id=866368d6313e41c38a6e600b1c5d8082-1545034860140-256948'.format(i*90)
    if i==0:
        url = 'https://fe-api.zhaopin.com/c/i/sou?pageSize=90&cityId=489&workExperience=-1&education=-1&companyType=-1&employmentType=-1&jobWelfareTag=-1&kw=%E6%95%B0%E6%8D%AE%E5%88%86%E6%9E%90%E5%B8%88&kt=3&_v=0.89067574&x-zp-page-request-id=866368d6313e41c38a6e600b1c5d8082-1545034860140-256948'

    page = urllib.request.urlopen(url).read()
    data = json.loads(page)
    time.sleep(random.uniform(1.2, 2.1))

    add_sql = """
    INSERT INTO zlzp_sjfx
    (job_number, job_type_big_num, job_type_big_name,job_type_medium_num,job_type_medium_name,company_num,company_url,company_name,
    company_size_num,
    company_size,
    company_type_num,
    company_type,
    job_url,
    working_exp_num,
    working_exp,
    edu_level_num,
    edu_level,
    job_salary,
    job_type,
    job_name,
    job_location_lat,
    job_location_lon,
    job_city,
    job_updatetime,
    job_createtime,
    job_endtime,
    job_welfare)
    VALUES (%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s)
    """

    for each_job in data['data']['results']:        
        add_data = (
            each_job['number'], # 編號
            each_job['jobType']['items'][0]['code'], # 職業大分類編號
            each_job['jobType']['items'][0]['name'], # 職業大分類名稱
            each_job['jobType']['items'][1]['code'], # 職業細分類編號
            each_job['jobType']['items'][1]['name'], # 職業細分類名稱
            each_job['company']['number'], # 公司編號
            each_job['company']['url'], # 公司對應url
            each_job['company']['name'], # 公司名稱
            each_job['company']['size']['code'], # 公司規模編號
            each_job['company']['size']['name'], # 公司規模
            each_job['company']['type']['code'], # 公司類型編號
            each_job['company']['type']['name'], # 公司類型
            each_job['positionURL'], # 職位對應url
            each_job['workingExp']['code'], # 工做經驗編號
            each_job['workingExp']['name'], # 工做經驗
            each_job['eduLevel']['code'], # 教育水平編號
            each_job['eduLevel']['name'], # 教育水平
            each_job['salary'], # 工資
            each_job['emplType'], # 工做類型
            each_job['jobName'], # 工做名稱
            each_job['geo']['lat'], # 經度
            each_job['geo']['lon'], # 緯度
            each_job['city']['display'], # 工做城市
            each_job['updateDate'],
            each_job['createDate'],
            each_job['endDate'],
            '/'.join(each_job['welfare']) # 工做福利
            )

        cursor.execute(add_sql, add_data)
        
    try:
        db.commit()
        print('page', i, 'done!用時', time.time()-time_0)
    except:
        db.rollback()
        print('page', i, 'not done')
        
# 關閉遊標
cursor.close()
# 關閉數據庫鏈接
db.close()
相關文章
相關標籤/搜索