python解決api變化的問題

案例:http://cic.org.vn/html

  該網站用python進行模擬登陸時,url連接是通過js加載生成的,當咱們用requests發送get請求的時候,返回的結果並非真正的主頁數據,而是一段js代碼,可是直接從這段js代碼中解析咱們須要的登陸頁url很困難,所以這裏咱們能夠構造一個輕量級的js環境,執行js代碼來獲取咱們須要的數據。node

環境:

咱們經過jsdom來構造一個輕量的環境,它是基於node的,所以咱們須要安裝node環境,這裏安裝的是node8的版本;python

curl -sL https://deb.nodesource.com/setup_8.x | sudo -E bash -
sudo apt-get install -y nodejs

安裝jsdom;web

npm install jsdom

建立js的運行環境;npm

js_env = '''
    const jsdom = require("jsdom");const { JSDOM } = jsdom;
    const dom = new JSDOM(`<!DOCTYPE html><p>Hello world</p>`, {
        url: "%s",
        contentType: "text/html;charset=utf-8",
        includeNodeLocations: true,
        storageQuota: 10000000
    });
    const window=dom.window;
    const document=dom.window.document;
    const navigator = dom.window.navigator;
    '''

爬蟲;

導包;bash

# -*- coding: utf-8 -*-

import execjs
import requests
from scrapy import Selector

構造請求;session

sess = requests.Session()

headers = {
    'Host': 'cic.org.vn',
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:49.0) Gecko/20100101 Firefox/49.0',
    'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
    'Accept-Language': 'en-US,en;q=0.9',
    'Accept-Encoding': 'gzip, deflate, br',
    'Connection': 'keep-alive',
    'Upgrade-Insecure-Requests': '1'
}

url = "http://cic.org.vn/"
res = sess.get(url=url, headers=headers)
html = Selector(text=res.text)
js = html.xpath("/html/head/script/text()").extract_first()

將咱們獲取的js代碼加載到咱們能構建的js運行環境中;app

ctx = execjs.compile(js_env % res.url + js)

執行js獲取生成的下一個連接;dom

next_url = ctx.eval("href") + ctx.eval("query")
print(next_url)

# 結果
https://cic.org.vn/webcenter/portal/CMSPortal/;jsessionid=4Hej6rGiIAbPiBs6nsBUMP61E9XNGVRYkRzjI5H0kxOhUW9dTaqR!873813657?_afrLoop=715225492645337

接下來的步驟都相似上一步,直到咱們最終獲得登陸的url;curl

最後咱們就能夠正常的模擬登陸進行操做抓取數據了。

總結:

  本次的案例是我第一次遇到的爬蟲狀況,該網站的主頁url也是通過js加載的,其參數是一直變化的,其返回的結果並非主頁的數據,所以咱們沒法直接從返回的數據中解析出咱們須要的參數,因此咱們構造這麼一個輕量級的js環境進行交互,直接問詢咱們須要的url參數,到最終獲取咱們須要的登陸頁連接中間這種js交互須要3次。

相關文章
相關標籤/搜索