SVG反爬蟲不同于字體反爬蟲,它巧妙的利用css 與 svg的關系,將字符映射到網頁中,看起來雖然正常,但是卻抓取不到有效內容。本文帶你深入淺出,破了SVG反爬蟲的套路,學會之后,可應用于某點評網。
一、初識SVG反爬:
為了防止面對監獄編程,我在本地自己做了一個網頁用于爬蟲測試。任務是爬取票據中的產品價格信息,按照往常一樣審查元素定位目標節點,但是發現事情并不簡單。
看圖:
¥符號后面并沒有我們想要的價格信息,而是四個d標簽取而代之。隨便選中一個7,發現對應的是屬性class=lhtqsc的d標簽。
看css樣式:
有兩段描述這個標簽的語句,第一段比較常規,但是其中的
就有點奇怪,而第二段,描述的是background,它的值是兩個 大小值,單位px。
打開svg文件查看:
貌似是沒什么規律的數字
查看該頁面網頁源代碼,發現是張這樣的:
二、什么是SVG?
想要搞定SVG反爬蟲就得先搞清楚SVG:
SVG是一種基于xml用于描述矢量圖的圖形格式,由于矢量圖放大或縮寫都不會影響圖形的質量,所以被較多的應用在web站點與App中,常見的存在形式是圖標。
編寫一個SVG文件:
為了方便,我們可以把要寫的svg,寫到html文件中,新建一個svg.html鍵入如下內容:
瀏覽器打開如下:
其中:
很關鍵,這一行用text標簽定義了一段文本,fill是文本顏色屬性,為紅色,并且指定了文本的坐標。該坐標的規則是:
- 以左上角為坐標系的原點(0,0)
- X 軸的正方向向右,從 0,0 點開始向右, x 逐漸增大。Y 軸的正方向向下,從 0,0 點開始向下, y 逐漸增大。
- 坐標以像素為單位
- n 個字符可以有 n 個位置參數。
增加一行:
這行代碼指定了前九個字符的位置,且指定了文本的顏色,y的值也增大到100,瀏覽器打開如下:
再次增加一行:
上圖可以看到,在不改變文本順序的情況下通過改變x中的值,讓第一個字符I和第四個字符o交換了位置。
三、SVG與CSS的聯系:
現在我們嘗試把css和svg聯系起來,更加深入的理解,方便我們做下一步抓取工作:在svg中,X軸正方向為從左到右,y軸的正方向是從上到下;在css中,X軸負數向右,Y軸是負數向下。一圖勝千言:
所以,CSS與SVG剛好相反。新建一個zhiliao.svg并鍵入:
我們在style中 定義了字符的風格,大小(14px),以及顏色(#666)。定義了每個字符所在的位置。
現在我們對第一個字符h進行定位,
X軸計算法則:字符大小 / 2 + 字符的x軸起點位置參數
Y軸計算法則:(y 軸高度 - 字符 y 軸起點 - 字符大小)/ 2 + 字符 y 軸起點位置參數 + 字符大小數值的一半
也就是:
X = 14/2 + 0 = 7
Y = (30 - 0 - 14) / 2 + 0 + 14 / 2 = 15
svg中對應的定位就是 x = 7 ,y = 15
css與svg相反,所以是 -7,-15現在
新建一個zhiliao.css文件,鍵入如下內容:
新建一個demo.html,鍵入:
html中會引入css文件,css又會引入svg文件。通過d標簽的class屬性值讀取css對應的svg標簽,完成對svg的映射。然后把demo.html拖到瀏覽器,可以看到:
字符h完完整整的被我們成功的映射出來了。
搞懂了這些,反爬就不是難事了,我們要做的是讓程序搞定這些。
四、Python抓取數據:
回到剛才的目標網站,開始實戰抓取。
1.獲取css樣式文件與svg文件內容:
2.獲取匹配出class屬性值對應css參數,與字符大小:
測試尋找class=lhtqsc的css對應參數和字符大小,輸出如下:
打開對應css與svg文件驗證:
一致,成功!
3.觀察svg文件:
這里有四個text標簽,對應四個文本,每個文本X軸都是從0開始,并且以14遞增Y軸不相同的,分別是 38, 83 , 120 ,164文本順序也有所不同。現在我們get這些數據:
輸出:
到這一步,我們成功的分別取出了y的和text標簽的四個值,并組成了列表。但是,這些元素 幾乎沒有和 [‘38’, ‘83’, ‘120’, ‘164’] 中有相等的,
這對于我們尋找text標簽包含的文本值并不影響,我們找到最近接近的即可。我們仍然以 class=lhtqsc為例子,尋找它最近的y值,從而找出是哪個text標簽包含的值。完善我們的代碼:
輸出:
然后就可以利用切片的特性尋找到對應的數值啦!
輸出 7,有圖為證:
驗證:我們打開網站,看看對應的是不是數字7
到這里,就算成功了,是不是很簡單呢?跟我一起做一遍吧。