如何破解自如的反爬機制

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

問題地址html

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

開始解答這個問題,以下:python

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

什麼是雪碧圖

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

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

全部的數字都合在一張圖上。網站

價格展現

那麼爲了展現價格要怎麼作呢,前端代碼怎麼寫呢? 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設置圖片移位顯示不一樣的數字。url

說是雪碧圖呢?這裏沒有設置圖片的代碼啊。接着看下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 的前綴,以下:

static8.ziroom.com/phoenix/pc/…

訪問該地址,便會獲得與開頭相似的圖片,以下:

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

那麼有該圖,價格怎麼顯示?這就是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,相似於某種加密效果。最終就實現了反爬。

相關文章
相關標籤/搜索