轉載請注明出處: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