分布式爬虫的设计与实现
- 基本环境
- linux操作系统、pycharm集成开发环境
- 主要功能
- 设计并实现一种基于“C/S”结构的爬虫,在并发爬取的情况下实现对大规模网页的爬取,并提取出网页的相关信息。
- 关键技术
- python、mongodb、广度优先与深度控制
- 系统结构
- 实现方案
-
Mongodb数据库中用于存放url对应的记录,每条记录格式为:
{
“_id”:url,
“state”:OUTSTANDING|PROCESSING|COMPLETE
“deepth”:
} -
其中,用url作为id,使得数据库中的url唯一;state记录url的访问状态——未访问、正在访问、访问过;deepth代表当前url的深度,在广度优先情况下对深度进行控制。同时,mongodb的虽然不支持事务,但原子操作保证了多线程之间的并发同步。
-
Client端运行相同的爬虫程序,从mongodb数据库队列中取出url进行爬取页面;由于数据库存储速率的瓶颈,本次选择将页面存储在本地,通过正则表达式提取页面的url,并将其加入mongodb数据库队列。Client端采用“多线程+多进程”的方式,使用线程池和进程池,进程数目等于cpu核心数目,每个进程中线程数目为5。
- 主要难点
-
Mongodb数据库的远程连接
Python访问HDFS,一直失败
爬取速率不好控制,间隔时间需要手动调试,特别是在多线程+多进程下更难以控制速率 - 有待改进
-
使用数据库连接池
使用HDFS存储
在hadoop平台上运行爬虫程序
Mongodb队列需要进一步优化,如使用索引、数据压缩存储、搭建分布式mongodb
使用布隆过滤器,记录已经爬取的url - 相关技术点
-
http状态响应码
2XX:成功
3XX:跳转
4XX:客户端错误
5XX:服务器错误 -
网页抓取策略
广度优先:1)重要的网页离种子站点比较近;2)广度优先有利于并行爬虫。
基于队列实现广度优先;同时,限制爬取深度。 -
记录抓取历史
用HashSet集合保存:查询复杂度为O(1);消耗内存较大
Url经MD5处理后存入hashset:消耗内存较小
Url存入数据库:C/数据库模式下有利于并发操作
布隆过滤器:时间、空间效率高,但只在本地存储,不适于分布式并发操作 -
解析网页
用正则表达式:时间最快;容错能力有限
用beautifulsoup解析:时间比较慢;容错能力好
用lxml解析器:时间和容错能力均衡:css选择器、xpath -
网站评估
<网页根目录>/robots.txt查看网站限制信息
进入sitemap查看网站地图
Site:<网址>查看网站的规模 -
页面处理
提取超链接时,注意排除内部锚点,内部锚点以“#数字”开头
用Chrome的Inspector查看网页元素 -
项目源代码