在這篇文章中,我們將嘗試使用直觀的網頁分析工具(Chrome 開發者工具)對網頁進行抓包分析
更加深入的了解網絡爬蟲的本質與內涵
1、測試環境
瀏覽器:Chrome 瀏覽器
瀏覽器版本:67.0.3396.99 (正式版本) (32 位)
網頁分析工具:開發者工具
2、網頁分析
(1)網頁源代碼分析
我們知道,網頁有靜態網頁和動態網頁之分,很多人會誤認為靜態網頁就是沒有動態效果的網頁,其實這種說法是不對的
-
靜態網頁 是指沒有后台數據庫的不可交互網頁 ,常以
.htm
、.html
、.xml
為后綴 -
動態網頁 是指能與后台數據庫進行數據傳遞的可交互網頁,常以
.aspx
、.asp
、.jsp
、.php
為后綴
另外,目前很多動態網站都采取了 異步加載技術 (Ajax),這就是很多時候抓取到的源代碼和網站顯示的源代碼不一致的原因
至於如何爬取動態網頁,這里提供兩種方法:
-
一是下面即將講到的通過抓包分析 Ajax 請求
-
二是利用 Selenium 等工具進行動態渲染,這個可以參考我的另一篇文章 —— selenium的基本使用
下面我們以京東商品為例,分析如何通過 Chrome 進行抓包,我們首先打開某個商品的首頁
https://item.jd.com/10072615543.html
來到網頁空白處單擊鼠標右鍵,選擇 查看網頁源代碼
(或者使用快捷鍵 Ctrl+U
直接打開)
請注意,查看網頁源代碼 得到的是網站最原始的源代碼,也就是通常我們抓取到的源代碼
再次來到網頁空白處單擊鼠標右鍵,選擇 檢查
(或者使用快捷鍵 Ctrl+Shift+I
/ F12
直接打開)
請注意,檢查 得到的是是經過 Ajax 加載和 JavaScript 渲染的源代碼,也就是當前網站顯示內容的源代碼
經過對比之后,我們可以發現兩者的內容是不一樣的,這就是 異步加載技術 (Ajax) 的典型例子
就目前來說至少京東商品的價格是通過異步加載生成的,這里提供三種方法判斷網頁中某個內容是否為動態生成:
-
一是分析 查看網頁源代碼 生成的源代碼,可以在其中尋找動態請求的典型語句,也可以將其與 檢查 生成的源代碼進行比較
-
二是通過以下將要講解的網頁抓包分析來判斷,這種方法最為常用,應當好好掌握
-
三是一種取巧的方法,就是禁用 Chrome 瀏覽器的 JavaScript 加載
具體可以在 Chrome 的地址欄中輸入 chrome://settings/content/javascript 來到 JavaScript 的設置頁面
然后將 JavaScript 的選項關閉,這時候重新刷新網頁,就會看到原來顯示價格的地方出現了空白
這就表明原來的價格是通過 JavaScript 動態生成的
(2)網頁抓包分析
我們還是以京東商品為例進行講解,打開某個商品的首頁,嘗試抓取動態加載的商品價格數據
https://item.jd.com/10072615543.html
使用快捷鍵 Ctrl+Shift+I
或 F12
打開開發者工具,然后選擇 Network 選項卡 進行抓包分析
此時按下快捷鍵 F5
刷新頁面,可以看到開發者工具中出現了各種各樣的包,我們使用 Filter 對包進行過濾
首先,我們選中 Doc
,可以看到列表中只出現了一個包
一般來說,這個就是瀏覽器接收到的第一個包,用於獲取請求網站的原始源代碼
點擊 Header
可以看到它的頭部參數設置
點擊 Response
可以看到返回的源代碼,容易發現,它其實和 查看網頁源代碼
返回的信息是一致的
下面讓我們重新回到正題,對於動態加載的抓包分析,主要看 XHR
和 JS
選項卡即可
選中 JS
進行過濾,發現列表中出現了好多包,經過分析,我們篩選出下圖中加標記的包
這個包返回的是關於價格的信息,可是經過仔細分析發現,這些價格並不是屬於當前商品的,而是屬於相關商品的
但是怎么說這個包還是和價格相關的,我們還是先看看這個包的請求 URL 吧
https://p.3.cn/prices/mgets?callback=jQuery1609108&type=1&area=1_72_2799_0&pdtk=&pduid=1539779074977382417990&pdpin=&pin=null&pdbp=0&skuIds=J_25630711066%2CJ_26395831446%2CJ_20823451030%2CJ_11332156897%2CJ_14020547214%2CJ_26498549638&ext=11100000&source=item-pc
對包括 callback 等不必要的參數進行篩選,可以得到簡單而有效的 URL
https://p.3.cn/prices/mgets?skuIds=J_25630711066%2CJ_26395831446%2CJ_20823451030%2CJ_11332156897%2CJ_14020547214%2CJ_26498549638
直接用瀏覽器打開該 URL,可以看到返回的的確是包含價格信息的 JSON 數據(只可惜是其他商品的價格)
分析該 URL 的參數,可以推測 skuId 應該就是每一個商品獨一無二的標志了,那么我們所需要的商品的 skuId 究竟可以在哪里找到呢?
事實上,SKU 是一個在物流、運輸等產業中常用的縮寫,其全稱是 Stock Keeping Unit(庫存量單位)
即庫存進出計量的基本單元,現在已經被引申為產品統一編號的簡稱,每種產品均對應有唯一的 SKU
回顧我們剛開始進入的商品首頁,https://item.jd.com/10072615543.html
這其中不是就隱藏着當前商品的唯一號碼標識(10072615543)了嗎?不妨一試!
果然,訪問商品價格的完整 URL 我們就可以得到了,https://p.3.cn/prices/mgets?skuIds=10072615543
通過直接訪問該網址我們就可以得到當前商品的價格信息
事實上,我們還可以對該 URL 進行適當的泛化以適應京東所有商品的價格爬取
很簡單,只需要將 skuIds 作為參數獨立分離出來即可,https://p.3.cn/prices/mgets?skuIds={ID}
通過泛化后的 URL ,理論上只要能得到商品的 skuId,我們就可以訪問對應商品的價格
【爬蟲系列相關文章】