如何破解自如的反爬機制

在知乎上看到了一個提問,大概意思是使用xpath爲什麼無法獲取到租房價格信息。問題的鏈接在這裏:

問題地址

看到問題,我也以爲很好解決,想着很快寫完答案就結束了。結果發現自己是too young too simple。要爬取的網址來自 自如租房

開始解答這個問題,如下:

看到你這問題 本來想介紹一下xpath,結果發現自己 too young too simple。看樣子自如爲了反爬竟然用上了雪碧圖來顯示價格,而且最關鍵的是 這個雪碧圖中數字的顯示順序是隨機的,每次刷新都會換一張圖。

什麼是雪碧圖

什麼是雪碧圖?簡單說來就是通過把所有圖片合成一張大圖,然後以移位方式展示圖片其中的某一部分。雪碧圖的好處就不說了。而且自如用雪碧圖的目的也只是爲了反爬。

來具體看看雪碧圖的工作原理,我們就來看下自如用來顯示價格的這張雪碧圖,如下:

所有的數字都合在一張圖上。

價格展示

那麼爲了展示價格要怎麼做呢,前端代碼怎麼寫呢?
HTML 部分,如下:

<p value="" class="price">
  <span style="background-position:1000px" class="num rmb">¥</span>
  <span style="background-position:-240px" class="num"></span>
  <span style="background-position:-210px" class="num"></span>
  <span style="background-position:-150px" class="num"></span>
  <span style="background-position:-210px" class="num"></span>
  <span class="gray-6"> (每月)</span>
</p>

主要是通過css設置background-position設置圖片移位顯示不同的數字。

說是雪碧圖呢?這裏沒有設置圖片的代碼啊。接着看下CSS部分,如下:

body.ratio2 .price span.num {
    background-size: auto 30px;
    background-image: url(//static8.ziroom.com/phoenix/pc/images/price/e05092a2f84c9cca5e4d881535072ae1.png);
}

background-image設置顯示的背景圖片。我們可以把其中的url截取出來,然後加上 http 的前綴,如下:

http://static8.ziroom.com/pho...

訪問該地址,便會得到與開頭類似的圖片,如下:

注:不知道這些圖片是否會被經常清理,如果查看該回答時是不能打開該圖,可以去自如的網站重新查看。

那麼有該圖,價格怎麼顯示?這就是html中內嵌的css起作用了。再看顯示價格的html代碼:

<p value="" class="price">
  <span style="background-position:1000px" class="num rmb">¥</span>
  <span style="background-position:-240px" class="num"></span>
  <span style="background-position:-210px" class="num"></span>
  <span style="background-position:-150px" class="num"></span>
  <span style="background-position:-210px" class="num"></span>
  <span class="gray-6"> (每月)</span>
</p>

可以先來看一下,上面這段代碼展示的頁面是什麼樣子的?如下:

展示的價格是2090,然後繼續看下雪碧圖中數字的順序、html代碼中background-position以及css圖片展示大小(30px),就可以推出,顯示數字與background-position的關係是:

0px       1
-30px     7
-60px     4
-90px     3
-120px    5
-150px    9
-180px    8
-210px    0
-240px    2
-270px    6

代碼實現

如果雪碧圖是固定不變的,我們就可以寫出類似下面的代碼 :

position_text_map = {
    "background-position:0px": 1,
    "background-position:-30px": 7,
    "background-position:-60px": 4,
    "background-position:-90px": 3,
    "background-position:-120px": 5,
    "background-position:-150px": 9,
    "background-position:-180px": 8,
    "background-position:-210px": 0,
    "background-position:-240px": 2,
    "background-position:-270px": 6
}

price = 0
for span_selector in price_selector.xpath("/span[@class='num']"):
    position = span_selector.xpath('//div/@style')[0]
    price = price * 10 + position_text_map[position]
print(price)

到此便可計算出最終價格。

隨機順序

但是,我要非常可以可惜的是一句,沒這麼簡單,雪碧圖每次都是隨機生成的,所以只有網站知道每個position對應的數字是多少,而我們卻無法得知。

那麼,沒有辦法解決了嗎?當然不是,此時就需要用到ocr技術了,即圖片轉文字。這裏需要慶幸的是,價格需人眼好識別,所以沒有驗證碼那麼千奇百怪。我們可以從github找一些解決方案。

比如使用tesseract,提供了一套圖片文字識別的解決方案。github如下:

tesseract-ocr/tesseract

同樣我們也可以找到它對應的python封裝:

sirfz/tesserocr

只要我們成功識別出了雪碧圖中數字的順序,下面的事情就很好辦了。

總結

簡單來說,其實就是把價格上每個數字轉化圖片展示。而其中用的一個重要技術就是雪碧圖。通過這種方式就可以把具體的文字轉化爲相應的css,類似於某種加密效果。最終就實現了反爬。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章