爬蟲系列文章整理:
今天示範如何爬取動態載入的網站!
就是當使用者在頁面上觸發事件,javascript會對server發出一個請求,並把資料渲染回Client端。
他的優點是觸發資料載入的當下,使用者還是可以繼續使用該程序。
相信試一遍就會知道,要是爬蟲過程不能在網站上觸發特定事件,我們便拿不到需要的資料。這個時候會有兩種思路,一是用js其他語言模擬用戶在瀏覽器上的行為,進而觸發資料的載入。常見的解法有大家熟悉的selenium、PhantomJS、CasperJS等。
二是延續上一篇我們觀察登入時的POST request,這次是觀察js在client端後台向server請求了哪個資料檔。
這次我的目標網站是Moz Keyword Planner,大家可以先進到網站搜尋看看關鍵字推薦詞組,會發現按下查詢後的網址沒有改變,而是動態載入資料的。這是如果想抓相對應的關鍵字詞組推薦,勢必需要知道js在我查詢時請求了哪些資料。
我們打開Network Panel,在按下查詢時仔細觀察,可以發現一個網址含有api的json檔,裡面正是你在網頁上看到的查詢結果。
先說在前面,如果你也跟我一樣太過頻繁對同個網站發requests,到後來你的IP會很容易被鎖。
urllib.request
import sys, json
import urllib.request as ur
ELE2 = []
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.75 Safari/537.36'}
result = ur.urlopen('https://moz.com/explorer/api/2.2.7/keyword/suggestions/influencer?locale=en-US&strategy=default')
# json.loads將原本的text轉成json
resultJson = json.loads(result.read())
# 關鍵字詞組陣列物件的key叫作"suggestions"
resultJsonClean = resultJson['suggestions']
for item in resultJsonClean:
ELE2.append(item['keyword'])
# json.dumps是從json解碼成string,ensure_ascii是針對中文處理時維持原本的utf-8編碼
print(json.dumps(ELE2, ensure_ascii=False))
將以上片段組合起來:
# -*- coding: utf-8 -*-
import sys, json
import urllib.request as ur
ELE2 = []
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.75 Safari/537.36'}
result = ur.urlopen('https://moz.com/explorer/api/2.2.7/keyword/suggestions/influencer?locale=en-US&strategy=default')
resultJson = json.loads(result.read())
resultJsonClean = resultJson['suggestions']
for item in resultJsonClean:
ELE2.append(item['keyword'])
print(json.dumps(ELE2, ensure_ascii=False))