最近朋友公司在做线下商户相关的业务,需要获取大量商户的信息,想让我帮他从点评采集,心想这不是小菜一碟,老代码改改不就ok了,于是欣然答应,并大言不惭的说过两天就交货......
于是乎当晚就翻出7年前的老代码,信心满满的撸起来,一番折腾后发现页面上显示中文的地方实际都是html的标签,例如<b class=”xxxxx“>之类的,这种情况在店铺列表页不多,但是在店铺详情和更多评论的页面都是,因此要获取店铺信息和评论数据必须得过这关,接下来各种找资料,网上相关文章也不少,但都有些出入,因为点评得反爬策略也在不断更新,经过几个晚上奋战,终于交货了!实现的过程和思路大致如下,截至文章发布前本人亲测有效,希望对你有帮助!
第一步:确定一个比较容易获取的数据来源
点评有移动端/h5/pc
1、大众点评APP:移动端数据获取相对比较麻烦
2、北京美食,北京餐厅餐饮,北京团购,北京生活,优惠券-大众点评网 h5端只会显示部分评价,全部评价必须要下载app才能查看
3、https://www.dianping.com/ pc端门店页数虽有50页限制,但是可以通过增加筛选条件规避,查看评价没有限制
因此综合考虑选择pc端
第二步:cookie的获取
注册多个账号,弄个代理ip池,技术上都没啥问题,但是哥想教你一个更简单的办法,前提是你得有一个点评账号,登录点评然后通过开发者工具拿到cookie,见下图
你可能会想,这个cookie肯定会变,没错,但变的是部分,在一个会话周期内,只有最后两个参数会变,不信你不停刷新页面试试看。
第三步:如何规避被识别?
通常识别爬虫都是通过请求的header/IP/请求频率来甄别,点评也不例外,弄的太严格会影响正常用户访问,因此:
1、在请求的header里加上cookie/user-agent/accept,如果cookie过期,点评不会提示的,但是返回的数据(比如店铺的电话)里会用*代替有效内容,因此运行一段时间要主动去换下cookie。
2、控制好请求的频率,不要太规律,有点人性,每次请求采用随机数间隔1-5秒,如果遇到爬取到的页面没有有效数据,通常响应状态不是200(比如滑块验证或者提示验证码),这时就间隔10-15分钟后再运行,不用改cookie。
第四步:门店列表获取
店铺筛选列表页:http://www.dianping.com/城市/大类/小类
列表信息有限,我在这里只获取点名和id,把要爬的所有门店id和名称先存入数据库,其它信息都是进详情页获取,见下图
翻页的逻辑页很简单
前面说了最多不超过50页,因此筛选后最好控制在50页内,或者增加地区限制,缩小筛选范围
怎么解析html不是本文重点,我在这里就不细说了,每种语言用的包都不一样。
第五步:破解css反爬
此处是本文的核心,也是花的时间最久的,仔细看好哦!目前发现的规律如下:
1、店铺详情页 http://www.dianping.com/shop/店铺id
点评目前采用的是woff字体加unicode定位的方法,
首先通过加密标签的class类名获得font-family值
然后到对应的css文件中获得woff文件
回过头再来看前面的标签里的unicode值,下图的 其实就是woff文件中对应文字的key,通过这个key就可以到woff文件里找到对应的文字,那么如何解析woff文件也不是本文的重点,如果有兴趣可以留言,我再单独回复。
别以为到这就结束了!店铺详情页虽然有评论,但是不完整,如果想获得完整评论,继续往下看,评论页又是一种玩法哦!
2、所有评论页 http://www.dianping.com/shop/店铺id/review_all
这里可以获得某个店铺的所有评论,采用的是svg文件加css背景定位法,相对第一种简单但变换的更快,记住下面红框的内容,后面要用到
先打开上图的svg文件看下,见下图,path标签的id属性值对应textPath标签的xlink:href="#后面的值
那么想要确定对应的文字在哪一行就先要确定这个id,回到再上一张图的background属性的y值
这里的-2374*-1+23=下面红框里的2397
那么思路出来了,根据标签的class对应的background属性经过计算获得svg文件path标签d属性的第二个值,然后根据id=59找到对应的文字应该在xlink:href="#59"的textPath标签内,但是如何确定在这行的第几个呢?
这时就要用到background属性的x值-168.0px,标签的宽度是14px
168/14=12,看下图,”点“是不是在这行文字的第13个,如果按照数组的索引从0开始,那不就是12吗?思路又出来了!
这种方式,点评会经常变换定位的方式,通常会加marigin-left或margin-top,我们只需要在计算时考虑这些偏移量即可,了解这些套路后,你就能从容的跟点评小哥过招了,当然招数会经常变,但套路不会频繁的变。
第六步:店铺经纬度获取(加赠)
http://www.dianping.com/ajax/json/shopDynamic/shopAside?shopId=店铺id
返回信息包含经纬度,与腾讯地图使用同样的地理编码,按需转换即可。
总结
通篇都没有讲具体怎么写代码,我想既然想跟点评小哥过招,你至少得有一门语言玩的溜,因此也就不多罗嗦了,觉得有帮助请我喝杯咖啡呗 :)