1. 程式人生 > >爬蟲實戰【6】Ajax內容解析-今日頭條圖集

爬蟲實戰【6】Ajax內容解析-今日頭條圖集

就是 get請求 加載 執行 搜索 parse 編程 滾動 from

Ajax技術

AJAX = Asynchronous JavaScript and XML(異步的 JavaScript 和 XML)。
Ajax並不是新的編程語言,而是一種使用現有標準的新方法,當然也不是很新了,在97年左右,微軟就發明了ajax的關鍵技術,但是並沒有推廣;隨著Google eath、google suggest和gmail的廣泛應用,ajax才開始流行起來。
ajax最大的優點是在不重新加載整個頁面的情況下,可以與服務器交換數據並更新網頁的部分內容。
ajax不需要任何瀏覽器插件,但是需要用戶允許javascript的執行。

Ajax的應用

運用XHTML+CSS來表達資訊;
運用JavaScript操作DOM(Document Object Model)來執行動態效果;
運用XML和XSLT操作資料;
運用XMLHttpRequest或新的Fetch API與網頁服務器進行異步資料交換;
註意:AJAX與Flash、Silverlight和Java Applet等RIA技術是有區分的。

目前有很多使用ajax的應用案例,比如新浪微博,google地圖,今日頭條等。
今天我們借助今日頭條見一下ajax內容的解析,如何爬取這類網站的內容。

今日頭條的搜索功能

前幾天一直登不上今日頭條,估計網絡監管太嚴,很多咨詢類服務商都down掉了。。。
今天終於能打開了,趕緊來講一下ajax的內容。
【插入圖片,今日頭條的搜索功能】
技術分享圖片

上面圖片中可以看出利用今日頭條搜索一些關鍵字,可以返回很多內容,請看四個標簽,綜合、視頻、圖集和用戶,我們今天講一下圖集。也就是標簽選項卡設置為圖集,如何設置後面會講清楚。

Index頁的源代碼

假設我們搜索足球關鍵字(哈哈,不搜索美女了。。。),我們看一下網頁的源代碼是什麽情況。
【插入圖片,index源代碼】
技術分享圖片

源代碼中除了一些基本的html標簽,就是各種js了,沒有我們想要的一些url內容或者圖集的信息。
上面說過了,今日頭條采用了ajax技術來加載內容,那麽根據ajax技術的特點,肯定有一部分數據會從服務器發送到我們的瀏覽器上來,否則網頁不會顯示出這些圖集的內容。
那麽這些數據在哪裏呢?

Ajax加載的數據在哪?

打開瀏覽器的調試,請選擇網絡標簽,選擇XHR內容,看下面出現的幾個文件。
【插入圖片,如何打開ajax加載的內容】
技術分享圖片

我們看這幾個文件的類型,都是json格式的。
再看search_content的類容,除了offset的值改變止嘔,其他都是一樣的。因為我們滾動過頁面了,每頁正好顯示20項內容,想必讀者一下子就能明白這個offset的內容,就是用來加載多個頁面的控制器。
我們看一個search_content的消息頭:
【插入圖片,json的消息頭】
技術分享圖片

這時一個get請求,我們可以用requests庫的get方法直接來請求到json文件。但是url的內容是啥呢?
大家看一下上圖中的幾個參數,尤其是最後的cur_tab設置為3,因為3才表示的選擇的是圖集,1的話是綜合,2是視頻,上面提到過。
我們只要改變其中的offset參數,就能夠得到多個頁面,每頁20個內容。
我們再來看一下響應內容:
【插入圖片,json的響應信息】
技術分享圖片

因為是json格式的內容,裏面都是一些key:value格式的內容,我們主要關註data下面的20個內容,每個內容中都包含article_url關鍵字信息,這個信息就是打開每個圖集的url,我們通過這個url就能訪問具體的圖集了。

關於網站解析的內容今天就講到這裏,我們再來看一下代碼,如何獲取這些每個圖集的url。

1、獲取index頁面的json內容

import requests
from urllib.parser import urlencode
def get_page_index(offset):
    #cur_tab標簽一定要寫正確,3才代表圖集,很重要
    data={
        ‘offset‘:offset,
        ‘format‘:‘json‘,
        ‘keyword‘:‘足球‘,
        ‘autoload‘:‘true‘,
        ‘count‘:‘20‘,
        ‘cur_tab‘:‘3‘
    }
    url=‘https://www.toutiao.com/search_content/?‘+urlencode(data)
    try:
        response = requests.get(url)
        if response.status_code==200:
            #print(response.text)
            return response.text
        else:
            return None
    except Exception:
        print(‘請求索引頁出錯!‘)
        return None

我們設置了一個offset參數,這樣就能控制獲取哪一個頁面,也就是實現自動向下滑動的功能。
data是我們在get請求時url的參數內容,我們用一個字典來表示,使用urlencode來編碼。
這個訪問還是很順利的,並沒有再提交額外的header參數。

2、對json內容進行解析

import json
def parse_page_index(html):
    data=json.loads(html)
    result=[]
    if data and ‘data‘ in data.keys():
        for item in data.get(‘data‘):
            article_url=item.get(‘article_url‘)
            if article_url and (‘group‘ in article_url):
                result.append(article_url)
    return result

因為要解析json內容,所以導入了json庫。
我們要獲取的是json內容裏面,data標簽下各項裏面的article_url信息,所以設置了一些篩選,data信息中一定要包含‘data‘關鍵字才做解析。
由於我們想要圖集,雖然設置了cur_tab為3,但是返回的一些url還是不太規範,我們在url中設置一定要包含group字符串,才能視作圖集。
然後將每個url都添加到result列表中。

3、開啟多進程運行

from multiprocessing import Pool
def main(offset):
    html=get_page_index(offset)
    for url in parse_page_index(html):
        print(url)

if __name__==‘__main__‘:
    p=Pool()
    p.map(main,[i*20 for i in range(3)])

我們先打開3個頁面嘗試一下,采用多進程可以快一些,雖然現在代碼少,但是理念要掌握。
【插入圖片,url結果】
技術分享圖片

OK,今天就先到這裏,明天再繼續講一下如何在這些url中獲取圖片。

技術分享圖片

爬蟲實戰【6】Ajax內容解析-今日頭條圖集