在知乎上看到了一個提問,大概意思是使用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以下:
一樣咱們也能夠找到它對應的python封裝:
只要咱們成功識別出了雪碧圖中數字的順序,下面的事情就很好辦了。
簡單來講,其實就是把價格上每一個數字轉化圖片展現。而其中用的一個重要技術就是雪碧圖。經過這種方式就能夠把具體的文字轉化爲相應的css,相似於某種加密效果。最終就實現了反爬。