簡單python爬蟲爬取拉勾網職位信息

寫在前面:這裏要感謝網易雲課堂丘祐瑋老師,本篇博文內容都是基於老師所講內容而寫,想要學習python學習爬蟲的可以去看老師的課程

今天要分享的是使用python爬取拉勾網職位信息,這裏只爬取python職位信息用做爬蟲效果展示,想要深入的同學再看完本篇博文後可以繼續研究
代碼中用到的一些庫不懂的同學可以看一下之前寫的博文,裏面有介紹,這裏就不再重複說明了:
https://blog.csdn.net/qq_33722172/article/details/82469050
如下圖,搜索python,按之前經驗頁面python職位信息是訪問https://www.lagou.com/jobs/list_python?labelWords=&fromSearch=true&suginput= 獲得的
這裏寫圖片描述
然而事實真是如此嗎?
這裏寫圖片描述
可以看到並沒有獲取到,那麼有些web開發經驗的應該就能想到python職位信息是不是通過ajax異步獲取的呢?果不其然,再network-XHR中我找到了這個請求,返回的json數據中有python職位信息
這裏寫圖片描述
那麼這裏就可以請求這個鏈接應該就能獲取到我們想要的數據了吧?是的,但是要注意這裏還有個陷阱
這裏寫圖片描述
這裏的請求用的是POST請求,那麼POST請求我們應該能想到在請求時肯定給服務器傳遞了數據
這裏寫圖片描述
這裏寫圖片描述
在構造模擬請求時一定要帶上form data中的數據,而且因爲是通過ajax獲取的數據,所以header頭裏的信息也要帶上(特別是一些我們平常沒見過的頭信息,它很可能是網站自己設置的驗證信息)如下:

headers = {
        'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 UBrowser/6.2.4094.1 Safari/537.36',
        'Host':'www.lagou.com',
        'Referer':'https://www.lagou.com/jobs/list_python?labelWords=&fromSearch=true&suginput=',
        'X-Anit-Forge-Code':'0',
        'X-Anit-Forge-Token':None,
        'X-Requested-With':'XMLHttpRequest'
    }
content = []
formdata = {
       'first':'true',
       'pn':1,
       'kd':'python'
} 
res = requests.post('https://www.lagou.com/jobs/positionAjax.json?city=%E5%8C%97%E4%BA%AC&needAddtionalResult=false',headers=headers,data=formdata)
res.encoding = 'utf-8'
html = BeautifulSoup(res.text, 'html.parser')

結果如下:
這裏寫圖片描述
在線格式化一下,可以看到我們想要的職位信息
這裏寫圖片描述

同樣不難猜到form-data中的pn參數應該就是當前頁數了,那麼我們只需要改變pn就能夠獲取不同頁的python職位數據了
有了列表信息,那麼接下來就是獲取詳細信息了,隨便打開一個職位,顯示如下:
這裏寫圖片描述
現在我們要獲取職位描述,右鍵審查元素
這裏寫圖片描述
通過觀察,我們可以看到職位描述在dd標籤中,class爲job_bt

url = 'https://www.lagou.com/jobs/4938653.html'
    headers = {
        'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 UBrowser/6.2.4094.1 Safari/537.36',
        'Host':'www.lagou.com',
        'Pragma':'no-cache',
        'Referer':url,
        'Upgrade-Insecure-Requests':'1'
    }
    res = requests.get(url,headers=headers)
    res.encoding = 'utf-8'
    info = BeautifulSoup(res.text, 'html.parser')
    return info.select('.job_bt')[0].text

結果如下:
這裏寫圖片描述
同樣我們可以看到https://www.lagou.com/jobs/4938653.html 中的49386553就是這個職位的唯一id了,從上面返回的職位列表json數據中也能證實這一點
到此我們已經能夠獲取每頁的職位列表信息以及每個職位的詳細描述
那麼整合一下上述代碼,一個完整的爬取拉勾網職位信息爬蟲如下:

import requests
from bs4 import BeautifulSoup
import json
import time
def getpositioninfo(id):
    url = 'https://www.lagou.com/jobs/%s.html' % id
    headers = {
        'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 UBrowser/6.2.4094.1 Safari/537.36',
        'Host':'www.lagou.com',
        'Pragma':'no-cache',
        'Referer':url,
        'Upgrade-Insecure-Requests':'1'
    }
    res = requests.get(url,headers=headers)
    res.encoding = 'utf-8'
    info = BeautifulSoup(res.text, 'html.parser')
    return info.select('.job_bt')[0].text
def getpositionlist(): 
    headers = {
        'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 UBrowser/6.2.4094.1 Safari/537.36',
        'Host':'www.lagou.com',
        'Referer':'https://www.lagou.com/jobs/list_python?labelWords=&fromSearch=true&suginput=',
        'X-Anit-Forge-Code':'0',
        'X-Anit-Forge-Token':None,
        'X-Requested-With':'XMLHttpRequest'
    }
    content = []
    for i in range(1,6):
        formdata = {
            'first':'true',
            'pn':i,
            'kd':'python'
        }
        res = requests.post('https://www.lagou.com/jobs/positionAjax.json?city=%E5%8C%97%E4%BA%AC&needAddtionalResult=false',headers=headers,data=formdata)
        res.encoding = 'utf-8'
        html = BeautifulSoup(res.text, 'html.parser')
        jd = json.loads(html.text)
        page_contents = jd['content']['positionResult']['result']
        for v in page_contents:
            position_dict = {
                'position_name':v['positionName'],
                'workyear':v['workYear'],
                'salary':v['salary'],
                'district':v['district'],
                'company_name':v['companyFullName']
            }
            position_id = v['positionId']
            position_detail = getpositioninfo(position_id)
            position_dict['position_detail'] = position_detail
        content.append(page_contents)
        time.sleep(5)
    line = json.dumps(content,ensure_ascii=False) #以json格式輸出,不使用ascii編碼
    with open('lagou.json','w') as fp:
        fp.write(line.encode('utf-8')) #寫進文件以utf-8格式
if __name__=='__main__':
    #getpositioninfo(5068139) #測試用
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章