分布式爬虫的设计与实现



分布式爬虫的设计与实现

基本环境
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查看网页元素

项目源代码

GitHub地址