在知乎上看到了一个提问,大概意思是使用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,相似于某种加密效果。最终就实现了反爬。