背景
春节过后回京,本想好好休息两天结果家里迎来了不速之客——老鼠。***通过一系列的操作终于成功捕获一家 8 口,这个过程笔者就不做多描述了。由于此次捕鼠事件留下阴影决定搬离。和媳妇开始寻找合适的房源,这还只是一个开始;之后看好房子(房子还在配置中)跟管家约定好释放当日签约;和媳妇两台手机两台电脑抢房子结果还是失之交臂。就算是双十一也不过如此吧!
之后继续找房发现基于小区搜索房源结果很不准确(用地铁站能过滤出来的,但直接用小区名就是搜不全),再加上想对当前市场房源有一个更清晰的了解,于是便有了一个想法——能否通过爬虫自己做个检索来找房子。
开始
通过爬虫自己做个检索来找房子,有了这个想法后就试着做一下,首先有一个大概思路:
- 写一个爬虫程序,尽可能解析出房子相关信息作为字段存储。
- 将数据存放在 ES(Elasticsearch)中便于查找。
- 使用 kibana 实现查询和分析,因其作为 ELK 经典组件,在查询分析上的强大优势不再多言。
需开发的爬虫可分为如下模块:
- 控制模块:作为起始开关和任务管理
- 抓取模块:输入一个网址,输出网页内容
- 解析模块:接收一段内容,输出有价值的字段信息,以及下一页等更多待解析的任务
- 存储模块:简单的做一个 map 进行运行时去重,然后将信息写入 ES
整个架构和其他爬虫基本一样,但自如为防止爬虫,搜索结果最多显示50页,对应办法就是遍历重要的查询参数,比如城市、地铁站、房子类型等。于是解析模块的顺序大概是:
1. 城市列表解析器,用来解析不同城市(当然这里只需要北京)
2. 地铁站解析器,用来解析出不同的地铁站
3. 房屋列表解析器,用来解析每一页的房屋列表和下一页待解析的任务
4. 房屋详情解析器,用来解析房屋的详细信息,如朝向、面积、户型、楼层、阳台、室友等
这里需要注意几点:
1. 爬虫使用 golang,它本身没有解析库,可以用第三方的 css 样式选择器、xpath,也完全可以用正则搞定,这里主要用正则实现,部分地方试用了下 css 选择器。
2. 部分房间信息如地铁站、地铁线路、所属 url、阳台、装修风格在房屋详情中不容易提取,可以在上一级页面如房屋列表中获得。
3. 房租价格做了反爬虫处理,不容易获得,具体是价格为不同图片拼接,这些图片根据一个静态随机页面搭配 offset 进行判断,然后通过 ocr 进行基本图片识别就能得到。
在上一级的网页源码中可以发现对应的原始图片和序号,这样就很简单了。
接下来是图片识别,需要用到一个利器——tesseract(https://github.com/tesseract-ocr/tesseract/wiki)
尽管有这么个神器,但解析成功率依然不能保证 100%,尤其是在没有训练的情况下,因此就需要像上面代码中那样,在短期内想提高效率就添加部分人工识别的代码,并降低重复工作,也能基本满足需求。
接下来是写入存储,这里为快捷实现,我们用 docker 在本机运行 es 和kibana,如下:
需要注意:尽量使用高版本,5.6 以后的 es 镜像版本中都默认安装了 x-pack 并激活了基础版本的 license(即免费使用基础功能,在这里也够了)golang 对接 ES 可以使用官方的 client。代码如:
注意上面的 setSniff=false,如果不加会有如下报错:
在docker中运行es时,默认启动 sniffing 模式,es自动查找节点, 要确保 Elasticsearch 返回可从容器外部访问的 IP 地址。
解决方式为关闭 sniffing 或者配置 es 返回的主机地址,参考https://github.com/olivere/elastic/wiki/Docker
1. 配置 elasticsearch
- 将 network.publish_host 和 network.bind_host 配置为可从容器外部访问的地址
- 配置network.host (不用再单独配置network.bind_host 和 network.publish_host)
2. 禁用 sniffing
elastic.SetSniff(false)
最终,经过一番尝试,登录 kibana 开始新的探索:
比如,基于多条地铁线进行房源查找,甚至可以排除部分职业的室友,举个栗子,排除下自己。
然后在 kibana 的 Visualize 中进行更多的分析:
比如最贵的地铁站周边和地铁线周边,2号线因为是内环地铁线路,均价毫无争议***。地铁站圆明园算是景区之外,中关村最贵也合情理。整租方面因为双井附近有一些豪宅而略高,其他地区基本在9500左右。
市场行情:
整租6-7k最多,合租费用上2-3k则是***频,其次是3-4k,而我也总算知道为什么之前的房源那么抢手了,因为它比当地均价低了500多;而1500以下的为数不多的几个都在远郊。
房源的情况:
可以看到大部分自如客住的都在20平内,占比约76%,如果细分的话可以看到10-15是***比的,而10号地铁线的房源最多。
房源最多集中在顶楼,这些多数是没电梯的老楼;而带独立阳台的,则只有20%;而从朝向上看,虽然南的比例***,但非南的加起来也远超它,可见大多数人都和阳光处的不太好。
从租客信息可知,男女比例相差不多,但星座上天秤座却比射手多好些。而从职业上看,IT行业(开发研发、测试、运维)占比远比其他要高,而他们又最多分布在8号线和13号线(西二旗表示很淡定自如)。
关于季节:
2月份是过去一年的高峰期,大量的人合同到期,也有大量的人重新签约,这里涉及到无数个小家的迁入和迁出,无数个打包和解包,无数个的——重新开始!
经过一番折腾,新房也找好了,等着过阵子搬过去。总结之后,生活还是要继续,也许还会在新家遇到老鼠,也一定会再随着生活变迁而搬到其他地方,但在这次“折腾”里,我得以用另一个视角去看自己,看待我和群体的关系,看待我们和这座城市的关系,以便更好的选择我们的未来。
注意:
以上只是个人基于部分数据所得做的简单分析,无法保证精确。
爬虫应在不对目标服务器产生较大干扰的情况下操作,可通过channel+time.Tick 进行主动限速。