網絡爬蟲之動態內容爬取

  根據聯合國網站可訪問性審計報告,73%的主流網站都在其重要功能中依賴JavaScript。和單頁面應用的簡單表單事件不通,使用JavaScript時,再也不是加載後當即下載全部頁面內容。這樣會形成許多網頁在瀏覽其中展現的內容不會出如今HTML源碼中,針對於這種依賴於JavaScript的動態網站,咱們須要採起相應方法,好比JavaScript逆向工程、渲染JavaScript等方法。html

1. 動態網頁示例

  

  如上圖,打開智聯招聘主頁,輸入python,搜索會出現上面的頁面,如今咱們爬取上圖紅色標記出的連接地址python

  首先分析網頁,獲取該位置的div元素信息,我這裏使用的是firefox瀏覽器,按F12ajax

  

  看上圖,紅色標記就是咱們要獲取的連接地址,如今用代碼獲取該處連接試試看json

import requests
from bs4 import BeautifulSoup as bs

url = 'https://sou.zhaopin.com/?jl=736&kw=python&kt=3'
reponse = requests.get(url)
soup = bs(reponse.text,"lxml")
print(soup.select('span[title="JAVA軟件工程師"]'))
print(soup.select('a[class~="contentpile__content__wrapper__item__info"]'))

  輸出結果爲:[ ] [ ]api

  表示這個示例爬蟲失敗了,檢查源碼也會發現咱們抓取的元素實際是空的,而firefox顯示給咱們的倒是網頁當前的狀態,也就是使用JavaScript動態加載玩搜索結果後的網頁。瀏覽器

2. 對動態網頁進行逆向工程

  在firefox中按F12單擊控制檯,打開XHRcookie

  依次點開,並查看響應出內容app

  會發現最後一行有咱們要的內容,繼續點開results的索引0網站

  

  很好,這就是咱們要找的信息ui

  接下來咱們就能夠對第三行的網址進行爬蟲處理並獲取咱們的想要的json信息。

3. 代碼實現

  接下來提取首頁jobName中包含python的全部連接:

import requests
import urllib
import http
import json

def format_url(url, start=0,pagesize=60,cityid=736,workEXperience=-1,
            education=-1,companyType=-1,employmentType=-1,jobWelfareTag=-1,
            kw="python",kt=3):
    url = url.format(start,pagesize,cityid,workEXperience,education,companyType,\
                    employmentType,jobWelfareTag,kw,kt)
    return url;

def ParseUrlToHtml(url,headers):
    cjar = http.cookiejar.CookieJar()
    opener = urllib.request.build_opener(urllib.request.HTTPSHandler, urllib.request.HTTPCookieProcessor(cjar))
    headers_list = []
    for key,value in headers.items():
        headers_list.append(key)
        headers_list.append(value)
    opener.add_headers = [headers_list]
    html = None
    try:
        urllib.request.install_opener(opener)
        request = urllib.request.Request(url)
        reponse = opener.open(request)
        html = reponse.read().decode('utf-8')
    except urllib.error.URLError as e:
        if hasattr(e, 'code'):
            print ("HTTPErro:", e.code)
        elif hasattr(e, 'reason'):
            print ("URLErro:", e.reason)
        
    return opener,reponse,html

'''print(ajax)
        with open("zlzp.txt", "w") as pf:
            pf.write(json.dumps(ajax,indent=4))'''
if __name__ == "__main__":
    url = 'https://fe-api.zhaopin.com/c/i/sou?start={}&pageSize={}&cityId={}'\
            '&workExperience={}&education={}&companyType={}&employmentType={}'\
            '&jobWelfareTag={}&kw={}&kt={}&_v=0.11773497'\
            '&x-zp-page-request-id=080667c3cd2a48d79b31528c16a7b0e4-1543371722658-50400'
            
    headers = {"Connection":"keep-alive",
                "Accept":"application/json, text/plain, */*",
               'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:63.0) Gecko/20100101 Firefox/63.0'}

    opener,reponse,html = ParseUrlToHtml(format_url(url), headers)
    if reponse.code == 200:
        try:
            ajax = json.loads(html)
        except ValueError as e:
            print(e)
            ajax = None
        else:
            results = ajax["data"]["results"]
            for result in results:
                if -1 != result["jobName"].lower().find("python"):
                    print(result["jobName"],":",result["positionURL"])
                

   輸出:

相關文章
相關標籤/搜索