1. 程式人生 > >一起學爬蟲——如何爬取通過ajax載入資料的網站

一起學爬蟲——如何爬取通過ajax載入資料的網站

目前很多網站都使用ajax技術動態載入資料,和常規的網站不一樣,資料時動態載入的,如果我們使用常規的方法爬取網頁,得到的只是一堆html程式碼,沒有任何的資料。

請看下面的程式碼:

url = 'https://www.toutiao.com/search/?keyword=美女'
headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36 SE 2.X MetaSr 1.0"}

response = requests.get(url,headers=headers)
print(response.text)

上面的程式碼是爬取今日頭條的一個網頁,並打印出get方法返回的文字內容如下圖所示,值現在一堆網頁程式碼,並沒有相關的頭條新聞資訊
python ajax

內容過多,只擷取部分內容,有興趣的朋友可以執行上面的程式碼看下效果。

對於使用ajax動態載入資料的網頁要怎麼爬取呢?我們先看下近日頭條是如何使用ajax載入資料的。通過chrome的開發者工具來看資料載入過程。

首先開啟chrome瀏覽器,開啟開發者工具,點選Network選項,點選XHR選項,然後輸入網址:https://www.toutiao.com/search/?keyword=美女 ,點選Preview選項卡,就會看到通過ajax請求返回的資料,Name那一欄就是ajax請求,當滑鼠向下滑動時,就會出現多條ajax請求:
python ajax

通過上圖我們知道ajax請求返回的是json資料,我們繼續分析ajax請求返回的json資料,點選data展開資料,接著點選0展開資料,發現有個title欄位,內容剛好和網頁的第一條資料匹配,可知這就是我們要爬取的資料。如下所示:
python ajax

滑鼠向下滾動到網頁底部時就會觸發一次ajax請求,下面是三次ajax請求:

https://www.toutiao.com/search_content/?offset=0&format=json&keyword=%E7%BE%8E%E5%A5%B3&autoload=true&count=20&cur_tab=1&from=search_tab&pd=synthesis
https://www.toutiao.com/search_content/?offset=20&format=json&keyword=%E7%BE%8E%E5%A5%B3&autoload=true&count=20&cur_tab=1&from=search_tab&pd=synthesis
https://www.toutiao.com/search_content/?offset=40&format=json&keyword=%E7%BE%8E%E5%A5%B3&autoload=true&count=20&cur_tab=1&from=search_tab&pd=synthesis

觀察每個ajax請求,發現每個ajax請求都有offset,format,keyword,autoload,count,cur_tab,from,pd引數,除了offset引數有變化之外,其他的都不變化。每次ajax請求offset的引數變化規律是0,20,40,60...,可以推測offset是偏移量,count引數是一次ajax請求返回資料的條數。

為了防止爬蟲被封,每次請求時要把請求時都要傳遞請求頭資訊,請求頭資訊中包含了瀏覽器的資訊,如果請求沒有瀏覽器資訊,就認為是網路爬蟲,直接拒絕訪問。request header資訊如下:

headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3029.110 Safari/537.36 SE 2.X MetaSr 1.0",
"referer": "https://www.toutiao.com/search/?keyword=%E7%BE%8E%E5%A5%B3",
'x-requested-with': 'XMLHttpRequest'
}

完整程式碼如下:

import requests
from urllib.parse import urlencode

def parse_ajax_web(offset):
    url = 'https://www.toutiao.com/search_content/?'
    #請求頭資訊
    headers = {
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3029.110 Safari/537.36 SE 2.X MetaSr 1.0",
        "referer": "https://www.toutiao.com/search/",
        'x-requested-with': 'XMLHttpRequest'
    }
    #每個ajax請求要傳遞的引數
    parm = {
        'offset': offset,
        'format': 'json',
        'keyword': '美女',
        'autoload': 'true',
        'count': 20,
        'cur_tab': 1,
        'from': 'search_tab',
        'pd': 'synthesis'
    }
    #構造ajax請求url
    ajax_url = url + urlencode(parm)
    #呼叫ajax請求
    response = requests.get(ajax_url, headers=headers)
    #ajax請求返回的是json資料,通過呼叫json()方法得到json資料
    json = response.json()
    data = json.get('data')
    for item in data:
        if item.get('title') is not None:
            print(item.get('title'))

def main():
    #呼叫ajax的次數,這裡呼叫5次。
    for offset in (range(0,5)):
        parse_ajax_web(offset*20)

if __name__ == '__main__':
    main()

上面是爬取通過ajax請求載入資料網站的例子,如果想要其他的資料,可以動手自己寫,這裡只是搭了一個架子,各位可以嘗試將資料寫入到excel或者資料庫中。