案例: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次。