在咱们调试爬虫程序的时候 。单线程爬虫没什么问题 。但是当咱们在线上环境使用单线程爬虫程序去采集网页时 。单线程就暴露出了两个致命的问题:
采集效率特别慢 。单线程之间都是串行的 。下一个执行动作需要等上一个执行完才能执行对服务器的CUP等利用率不高 。想想咱们的服务器都是 8核16G 。32G 的只跑一个线程会不会太浪费啦线上环境不可能像咱们本地测试一样 。不在乎采集效率 。只要能正确提取结果就行 。在这个期间就是金钱的年代 。不可能给你期间去长久以来的采集 。所以单线程爬虫程序是行不通的 。咱们需要将单线程改成多线程的模式 。来提升采集效率和提升计算机利用率 。
多线程的爬虫程序设计比单线程就要复杂很多 。但是与其他业务在高并发下要保证数据安全又不同 。多线程爬虫在数据安全上到要求不是那么的高 。因为每个页面都可以被看作是一个独立体 。要做好多线程爬虫就一定做好两点:第一点就是统一的待采集 URL 维护 。第二点就是 URL 的去重 。下面咱们简单的来聊一聊这两点 。
维护待采集的 URL多线程爬虫程序就不能像单线程那样 。每个线程独自维护这自己的待采集 URL 。如果这样的话 。那么每个线程采集的网页将是一样的 。你这就不是多线程采集啦 。你这是将一个页面采集的多次 。基于这个原因咱们就需要将待采集的 URL 统一维护 。每个线程从统一 URL 维护处领取采集 URL。完成采集任务 。如果在页面上发现新的 URL 链接则添加到 统一 URL 维护的容器中 。下面是几种适合用作统一 URL 维护的容器:
JDK 的安全队列 。例如 LinkedBlockingQueue高性能的 NoSQL 。比如 Redis、MongodbMQ 消息中间件URL 的去重
URL 的去重也是多线程采集的关键一步 。因为如果不去重的话 。那么咱们将采集到大量重复的 URL 。这样并没有提升咱们的采集效率 。比如一个分页的新闻列表 。咱们在采集第一页的时候可以得到 2、3、4、5 页的链接 。在采集第二页的时候又会得到 1、3、4、5 页的链接 。待采集的 URL 队列中将存在大量的列表页链接 。这样就会重复采集甚至进入到一个死循环当中 。所以就需要 URL 去重 。URL 去重的方法就非常多啦 。下面是几种常用的 URL 去重方式:
将 URL 保存到数据库进行去重 。比如 redis、MongoDB将 URL 放到哈希表中去重 。例如 hashset将 URL 经过 MD5 之后保存到哈希表中去重 。相比于上面一种 。能够节约空间使用 布隆过滤器(Bloom Filter)去重 。这种方式能够节约大量的空间 。就是不那么准确 。关于多线程爬虫的两个核心知识点咱们都知道啦 。下面我画了一个简单的多线程爬虫架构图 。如下图所示:
文章插图
多线程爬虫架构图
上面咱们主要知道了多线程爬虫的架构设计 。下一步咱们不妨来试一试 java 多线程爬虫 。咱们以采集虎扑新闻为例来实战一下 Java 多线程爬虫 。Java 多线程爬虫中设计到了 待采集 URL 的维护和 URL 去重 。由于咱们这里只是演示 。所以咱们就使用 JDK 内置的容器来完成 。咱们使用 LinkedBlockingQueue 作为待采集 URL 维护容器 。HashSet 作为 URL 去重容器 。下面是 Java 多线程爬虫核心代码 。详细代码以上传 GitHub 。地址在文末:
文章插图
文章插图
文章插图
咱们用 5 个线程去采集虎扑新闻列表页看看效果如果?运行该程序 。得到如下结果:
文章插图
多线程采集结果
结果中可以看出 。咱们启动了 5 个线程采集了 61 页页面 。一共耗时 2 秒钟 。可以说效果还是不错的 。咱们来跟单线程对比一下 。看看差距有多大?咱们将线程数设置为 1。再次启动程序 。得到如下结果:
文章插图
单线程运行结果
可以看出单线程采集虎扑 61 条新闻花费了 7 秒钟 。耗时差一点是多线程的 4 倍 。你想想这可只是 61 个页面 。页面更多的话 。差距会一直变大 。所以多线程爬虫效率还是非常高的 。
分布式爬虫架构分布式爬虫架构是一个大型采集程序才需要使用的架构 。一般情况下使用单机多线程就可以解决业务要求 。反正我是没有分布式爬虫项目的经验 。所以这一块我也没什么可以讲的 。但是咱们作为技术人员 。咱们需要对技术保存热度 。虽然不用 。但是知道知道也无妨 。我查阅了不少资料得出了如下结论:
【Java和python爬虫有什么区别 java爬虫与python爬虫的区别】分布式爬虫架构跟咱们多线程爬虫架构在思路上来探讨是一样的 。咱们只要在多线程的基本上稍加改进就可以变成一个简单的分布式爬虫架构 。因为分布式爬虫架构中爬虫程序部署在不同的机器上 。所以咱们待采集的 URL 和 采集过的 URL 就不能存放在爬虫程序机器的内存中啦 。咱们需要将它统一在某台机器上维护啦 。比如存放在 Redis 或者 MongoDB 中 。每台机器都从这上面获取采集链接 。而不是从 LinkedBlockingQueue 这样的内存队列中取链接啦 。这样一个简单的分布式爬虫架构就出现了 。当然这里面还会有很多细节问题 。因为我没有分布式架构的经验
- 海参和海茄子的区别
- 手机充电时充电器和手机发热是为什么
- 手机吃鸡怎么调第一人称和第三人称 手机吃鸡怎么调第三人称
- 你下个月就要订婚了。 徐岁宁最后和洛之鹤在一起了吗
- 吃蜂蜜忌吃什么食物
- 蒲公英根和菊花能一起泡水喝吗
- 冰箱不制冷的原因分析及故障排除 商用冰箱不制冷的原因和解决方法
- web游戏源码素材网站 7个模板代码和游戏源码下载网站
- 绞股蓝七叶和五叶的区别
- 五叶和七叶绞股蓝哪个降压好