(9)分布式下的爬蟲Scrapy應該如何做-關於ajax抓取的處理(一)


轉載請注明出處:http://www.cnblogs.com/codefish/p/4993809.html

  

最近在群里頻繁的被問到ajax和js的處理問題,我們都知道,現在很多的頁面都是用動態加載的技術,這一方面帶來了良好的頁面體驗,另一方面,在抓取時或者或少的帶來了相當大的麻煩,因為我們知道直接get主頁頁面url,這些內容是沒有辦法顯示的。那怎么處理這些內容呢?

 

上圖是一個直觀的分析,在抓取數據時,我們一般優先考慮到手機端的網站,因為手機端的網站得到數據相對容易,特別是wap協議的網站,其分頁方式大多不是ajax分頁或者瀑布流的形式,所以抓取相對容易的多。另外在分析到請求頭之后,我們可以很方便得到ajax請求地址,這個時候直觀的去call這個地址,看能否正常的得到的數據。換了瀏覽器然后在call一次,看數據能否正常,如果正常,那個url可能就是public的,那在保障一定的頻率訪問之后就可以很容易的拿到數據。下面我用一個例子來說明分析請求的。

 

 

一,打開目標網站,查看加載方式:

https://www.abdserotec.com/primary-antibodies-monoclonal-polyclonal.html#productType=Monoclonal%20Antibody

 

二,分析網站

當我打開網站的時候,可以很明顯的發現數據是通過下拉列表,到底端之后解發ajax事件來請求數據的,那我們實際的去他在請求的時候都發生了哪些事情

 

我們得到請求地址了:

https://api.uk-plc.net/product_tables/v1/abd?filter={%22productType%22:{%22$in%22:[%22Monoclonal%20Antibody%22]}}&skip=360&limit=40&sort=[[%22specificitySummary%22,1],[%22host%22,1],[%22uniqueName%22,1],[%22format%22,1]]

 

那我直接在瀏覽器打開看看:

 

很顯然的看到了熟悉的json格式的字符串

 

別急,這里我們需要更換瀏覽器打開剛剛的api接口,為什么要這樣做?因為我們現在打開的時候都會帶上了一定的請求參數,我們更換瀏覽器就是清掉這些參數,然后再來訪問,如果還是得到數據,這樣說明這個api接口本身就是public的,而且管理員對這個接口沒有做filter 。

 

三,進一步分析參數

OK,這直接說明了可以直接訪問這個接口,那如何分頁呢?

我們來看URL里面都有哪些參數:

https://api.uk-plc.net/product_tables/v1/abd?filter={%22productType%22:{%22$in%22:[%22Monoclonal%20Antibody%22]}}&skip=360&limit=40&sort=[[%22specificitySummary%22,1],[%22host%22,1],[%22uniqueName%22,1],[%22format%22,1]]

 

skip=360

limit=40

這和C# linq的分頁的方式何其的相似, 那我可以這樣大膽假設一下:

limit 就是pagecount,每頁的數量

skip就是略過第幾頁的數據

 

pageindex 第幾頁

 

那相應的取得幾頁的數據就是:

skip =(pageindex-1)*pagecount

limit = 40 

驗證一下,數據還是得到

 

四,寫代碼

這里面我用python 寫了一個簡單的腳本:

__author__ = 'Bruce'
import requests

page_count = 20
page_index = 1
url_template = 'https://api.uk-plc.net/product_tables/v1/abd?filter={%22productType%22:{%22$in%22:[%22Monoclonal%20Antibody%22,%22Polyclonal%20Antibody%22]}}&skip={page_index}&limit={page_count}&sort=[[%22specificitySummary%22,1],[%22host%22,1],[%22uniqueName%22,1],[%22format%22,1]]'


def get_json_from_url(url):
    r = requests.get(url)
    return r.json()['results']


def init_url_by_parms(page_count=40, page_index=1):
    if not page_count or not page_index:
        return ''
    return url_template.replace('{page_index}', str((page_index - 1) * page_count)).replace('{page_count}',
                                                                                            str(page_count))


if __name__ == '__main__':
    url = init_url_by_parms(page_count=page_count, page_index=page_index)
    print url
    objs = get_json_from_url(url)
    if objs:
        for obj in objs:
            print '####################################'
            for k, v in obj.items():
                print k, ':', v

 

另外,朋友說如何得到總頁數呢?我們假定以現有的40頁的數據量,假定總頁數為100,如果第100頁有數據,那訪問第200頁,如果沒有得到數據,那訪問第(100+200)/2頁數據,依此類推,差不多log2N次就可以得到總頁數,這里就用二分法就可以得到。

 

總結:

本次文章主要分析ajax可以直接調用和分析請求的過程,在我看來,碼代碼通過思考來分析問題,比硬寫代碼死磕來的強的多,下次我將分析一下直接call ajax接口沒辦法解決的情況.

 轉載請注意出處:http://www.cnblogs.com/codefish/p/4993809.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM