范鹏程 涂嘉庆
摘要:该文基于Scrapy框架研究并实现了爬取温州租房信息的爬虫程序,程序采用分布式结构,运用去重算法去除重复URL提高爬虫的效率,并针对反爬虫策略提出多种解决方法。爬取的信息存储在MongoDB数据库中,最终通过测试和分析得出位置、朝向对温州租房价格的影响,得出租房性价比较高的方案。
关键词:租房爬虫;Scrapy框架;分布式;去重策略
中图分类号:TP274.2 文獻标识码:A
文章编号:1009-3044(2019)18-0004-03
Abstract: Based on the Scrapy framework, this paper studies and implements a crawler program for crawling Wenzhou rental information. The program adopts distributed structure, uses the de-duplication algorithm to remove duplicate URLs to improve the efficiency of crawler, and proposes various solutions for anti-crawler strategy. The crawled information is stored in the MongoDB database. Finally, the influence of location and orientation on the rent price of Wenzhou was obtained through testing and analysis, and gets a cost effective rental solution.
Key words: rent crawler; Scrapy framework; distributed strategy; de-duplication strategy
1 背景
随着我国房价的不断攀升,越来越多人选择租房,特别是一些经济发展比较靠前的城市,目前中国租房的人口已经达到2亿多,数据显示有将近三分之二的人通过网络来获取租房信息,有70%左右的房东会将租房信息挂在网上,但网上租房信息资源比较分散,当需要进行数据分析筛选出性价比合适的租房信息时需要消耗大量的时间去进行人工比对,十分不便。
温州春节后有大量的外来务工人员回归,其中大多数会选择租房,这个时间也是各个高校开学的时间,有大量的学生租房,如何选择一个性价比适合的房子就非常重要,本文基于Scrapy框架设计爬虫程序爬取温州租房信息,运用聚焦爬虫收集温州租房信息并筛选和分析,研究租房的朝向、位置对于温州房价的影响,如何租房性价比最高。
2 相关技术
2.1 爬虫技术
网络爬虫(Web crawler)也叫网络蜘蛛(Web spider),蚂蚁(ant)[1],是由程序设计者编写的能自动抓取网页信息并加以解析存储的程序。一般先指定一个或多个初始的URL作为种子,在不断抓取网页信息的过程中将爬取到的新 URL存入URL访问队列中,在爬取完当前网页资源后从URL访问队列中调出一个再次进行爬取,一直重复到满足程序设计者的停止条件或者爬完URL队列为止,爬取出的网页资源会进行一定的解析、筛选然后存储入数据库中。本文研究的主要是聚集网络爬虫,聚焦网络爬虫顾名思义就是聚焦于一个主题,将与主题相关的网页资源爬取并保存下来的爬虫。
2.2 Scrapy框架
Scrapy是Python编写的Crawler Framework,具有结构简单、使用方便等特点[1]。Scrapy框架包含并发、存储、监控等功能,并且框架提供基于Twisted异步的爬取,吞吐量十分可观,爬取速度更快。
其基本工作原理就是Scrapy Engine作为大脑控制Spiders,Spiders让Scheduler调出队首的URL给Downloader,Downloader去网上下载相关的网页资源交给Spiders对资源进行分析、筛选,再转交给Item Pipeline进行数据库保存,而在URL中解析出来的新的URL将被存入Scheduler的队列中,循环上述抓取步骤,当Scheduler的队列为空停止。
2.3 分布式爬虫
分布式爬虫的构架通常由一个Master服务器和若干个Slave服务器组成,Master服务器管理Redis数据库中URL队列,每当一个Slave服务器中的Scrapy爬虫完成网页资源的爬取,Master就会再分配一个队首URL给Slave服务器,使爬虫继续爬行,而在爬取网站资源的过程中遇到的新URL则会继续添加到Redis数据库队列中,当Redis数据库为空或者满足设定值时就停止爬取。这种分布式的构架让多个爬虫公用一个URL队列,极大程度上加快了爬取效率,解决了Scrapy的单机局限性。
2.4 布隆去重
布隆过滤器是由巴顿布隆(Burton Howard Bloom)于1970年提出的一种基于多个哈希函数映射压缩参数空间的数据结构[2],是一种二进制向量数据结构,主要的功能是判断一个元素在不在一个集合内,爬取网站的过程中需要保存大量的URL,当获得一个新的URL时,需要先判断这个URL是不是已经爬取过了,如果已经存在了将跳过这个URL,不再进行保存。
布隆去重是内存去重的一种方法,不必在每一次判断的时候都去调用数据库查询,而是在最初创建一个空的Bitmap集合,将得到的URL拆成多段,利用哈希算法生成相应个数的哈希值,然后将其映射到Bitmap集合中,若下一个URL拆封成多端经过哈希算法运算映射到Bitmap集合位置上的数值不全为1,则说明这个URL没有被访问过,若数值全为1则可能访问过也有可能没有访问过,所以这一种算法会有一定的误判率,但是却能带来存储空间的极大节省。
2.5 反爬虫策略
当运行爬虫对网站进行访问时,网站会在后台对访问进行统计,设定单个IP访问的阈值,如果一个IP地址在短时间内访问频率超过阈值,可以暂时对这个IP予以封锁[3],从而导致爬虫无法正常运行,最终爬取信息失败,所以可以合理的切换代理IP和使用分布式爬虫来解决此问题。
当在一个网站访问次数过多时网站会弹出验证码,输入错误会导致爬虫不能继续爬取,可以利用第三方库tesserocr來解决一部分容易识别的验证码,有背景的验证码则需要先对图片灰度化,这样的识别率会更高。
3 爬虫设计与实现
3.1 目标网站选取
租房的房源一定要真实可靠,现在比较大且知名的租房网站有58同城、赶集网等,通过研究发现,58同城中的房源信息与其他网站有很高的重复率,而且58同城的租房网站中的价格参数并不能直接从爬取的HTML代码中能得到,其中价格参数是通过Base64加密以后存放在JS中,每次刷新网页时其中的映射关系都会再次发生改变,所以获取价格都需要重新解密映射,浪费了时间又十分不便,赶集网中数据对比与58同城的租房数据有很高的重合率,没有加密和JS渲染,可以提高爬虫效率同时又降低了爬虫制作难度,所以选取赶集网进行爬取。
3.2 爬虫爬取流程
爬虫开始爬取时需要一个或若干个链接作为种子,作为种子链接的网页资源可以继续拆封为若干个分页链接,将链接放入一个队列中,爬取到的租房信息存储到数据库中,若有下一页则将下一页的URL放入访问的队列中,循环这个过程直到队列为空或满足停止条件停止爬虫,流程图如下:
3.3 数据采集
3.3.1 Item设计
Item是Scrapy框架中的一种简单容器,将抓取有一定关联的非结构化数据保存成结构化数据,用于Pipelines数据库存储操作。
Scrapy框架中Field对象可以接收所有的参数类型,没有值的限制,也没有任何属性。本文需要Field保存的租房参数有房间数、平方、朝向、装修程度、地点、来源、价格等信息。
3.3.2 Spider设计
Spider中首先确定爬取的初始URL:wenzhou.ganji.com/zufang/,其中又分为鹿城、平阳、龙湾、瓯海等地区,其URL格式为wenzhou.ganji.com/lucheng/chuzu/只用改动URL后缀参数就能更改地区,实现爬取不同地区的信息。
每个URL中会有多组数据,先利用Xpath对所需链接进行定位,Spider爬取并记录下链接,进入链接打包所需参数到一个Item对象转交给Pipelines,最后搜寻是否有下一页的链接,若有则加入访问的队列,若没有则切换地区进行爬取。
3.3.3 Middlewares设计
Middlewares.py中间件中设置IP代理可以有效防止同IP访问次数过于频繁而弹出验证码,在设置代理IP前首先需要获得大量IP代理,许多网站有免费提供代理IP的服务,可以写一个简单的爬取程序将稳定可用的IP爬取保留下来。
爬虫程序添加IP代理时需先在Setting配置文件中新增加IP池,池中加入用于切换的IP,Middlewares配置文件中设置Proxy对每次进行网站访问的IP进行变更,保证不连续使用同一个IP多次访问网站,当使用代理IP进行访问返回403错误时,说明这个IP已经失效了,需要切换IP代理。
3.4 数据存储
MongoDB是由C++语言编写的,是一个基于分布式文件存储的开源数据库系统[3],在爬取数据存储数据库时不必关心表结构,可直接将字典结构的数据插入,十分方便。
Scrapy框架中运用MongoDB数据库需要先编写Settings,将MongoDB的连接参数写入,在Piplines文件中加入MongoDBPipline类用于连接数据库,在其中实现打开,关闭以及插入数据等方法,最后在插入方法中实现Item插入数据库的方法,将爬取到的温州租房信息插入数据库保存。
3.5 数据分析
1)从温州各区租房信息数量上看,租房信息最丰富的地区为鹿城区,占53%,瓯海区和龙湾区次之,分别占16%和10%,其余地方占据21%。
2)从月每平方米单价上看,鹿城区的平均单价最高,达到43.96元/月/m?,瓯海区排名第二,达到每月39.85元/月/m?,龙湾区排名第三,达到35.8元/月/m?,图中也能看出朝向对于平均单价有一定的影响,朝北的房子一般比朝南的房子低大约2.47~8.65元/月/m?不等,其中对于瓯海区的影响最大。
3)从温州热门地区租房价格图上看,鹿城区的价格排名第一,其中以装修精美的安澜小区的84元/月/m?在温州排名最高,瓯海区排名第二,以新鑫小区61.32元/月/m?在瓯海区排名最高,本文主要分析最热门的温州鹿城区:
4 结束语
温州租房性价比高的地区分别为鹿城区的东部西部、瓯海区的茶山附近、龙湾区的海滨和状元附近、瑞安市的安阳附近、乐清的柳市和翁洋地区附近、永嘉的瓯北附近,这些地区可以选择朝南装修稍好的房子,若需在鹿城区的南部、北部以及市中心位置租房,由于基础房租较高,可以选择不朝南且装修一般的房子,这两种选择方法性价比最高。
本文基于Scrapy框架编写了温州租房信息爬虫,通过数据比对分析筛选出具有性价比的温州租房位置,研究出朝向对房价的影响,但也存在一些问题,在爬取网页时Scrapy框架不支持具有JS渲染的网页,布隆去重有一定的误判率等,后续研究可以针对这几个问题进行完善。
参考文献:
[1] 马联帅. 基于Scrapy的分布式网络新闻抓取系统设计与实现[D]. 西安: 西安电子科技大学, 2015.
[2] 张笑天. 分布式爬虫应用中布隆过滤器的研究[D]. 沈阳: 沈阳工业大学, 2017.
[3] 安子建. 基于Scrapy框架的网络爬虫实现与数据抓取分析[D].长春: 吉林大学, 2017.
【通联编辑:谢媛媛】