Go 进阶 · 分布式爬虫实战
郑建勋
Go 语言技术专家,《Go 语言底层原理剖析》作者
15839 人已学习
新⼈⾸单¥68
登录后,你可以任选4讲全文学习
课程目录
已完结/共 58 讲
Go 进阶 · 分布式爬虫实战
15
15
1.0x
00:00/00:00
登录|注册

30|辅助任务管理:任务优先级、去重与失败处理

你好,我是郑建勋。
这节课,让我们给系统加入一些辅助功能,把爬虫流程变得更完善一些。这些功能包括:爬虫最大深度、请求不重复、优先队列、以及随机的 User-Agent。

设置爬虫最大深度

当我们用深度和广度优先搜索爬取一个网站时,为了防止访问陷入到死循环,同时控制爬取的有效链接的数量,一般会给当前任务设置一个最大爬取深度。最大爬取深度是和任务有关的,因此我们要在 Request 中加上 MaxDepth 这个字段,它可以标识到爬取的最大深度。Depth 则表示任务的当前深度,最初始的深度为 0。
type Request struct {
Url string
Cookie string
WaitTime time.Duration
Depth int
MaxDepth int
ParseFunc func([]byte, *Request) ParseResult
}
那在异步爬取的情况下,我们怎么知道当前网站的深度呢?最好的时机是在采集引擎采集并解析爬虫数据,并将下一层的请求放到队列中的时候。以我们之前写好的 ParseURL 函数为例,在添加下一层的 URL 时,我们将 Depth 加 1,这样就标识了下一层的深度。
func ParseURL(contents []byte, req *collect.Request) collect.ParseResult {
re := regexp.MustCompile(urlListRe)
matches := re.FindAllSubmatch(contents, -1)
result := collect.ParseResult{}
for _, m := range matches {
u := string(m[1])
result.Requesrts = append(
result.Requesrts, &collect.Request{
Url: u,
WaitTime: req.WaitTime,
Cookie: req.Cookie,
Depth: req.Depth + 1,
MaxDepth: req.MaxDepth,
ParseFunc: func(c []byte, request *collect.Request) collect.ParseResult {
return GetContent(c, u)
},
})
}
return result
}
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

本文介绍了如何在爬虫系统中加入辅助功能,包括设置爬虫最大深度、避免请求重复和设置优先队列。作者首先介绍了如何通过在Request中加入MaxDepth字段来控制爬取的最大深度,并在异步爬取中实现深度标识和深度检查。其次,为了避免爬取时的死循环,作者提出了使用哈希表来存储历史请求,并通过抽离出Task结构和调度引擎的抽象来实现并发安全的请求去重。最后,作者介绍了如何设置优先队列,将任务的优先级分为优先队列和普通队列,并修复了之前遗留的Bug。此外,文章还讨论了设置随机User-Agent和进行失败处理的方法。总的来说,本文通过实际代码示例,详细介绍了如何在爬虫系统中实现任务优先级、去重和失败处理等辅助功能,为读者提供了一些实用的技术指导。文章内容涵盖了爬虫系统的关键功能和技术要点,对于想要深入了解爬虫系统设计与实现的读者来说,具有很高的参考价值。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《Go 进阶 · 分布式爬虫实战》
新⼈⾸单¥68
立即购买
登录 后留言

全部留言(4)

  • 最新
  • 精选
  • Realm
    https://shimo.im/docs/5rk9dVyblnFzZLqx 根据课程讲解以及原代码,自己理解整理的调度过程。
    2022-12-18归属地:浙江
    4
  • Geek_crazydaddy
    把worker获取任务的channel换成channel切片,索引值就是优先级,然后用多个select按序监听这些channel,而且要加default,没读到就立即跳过?
    2022-12-17归属地:江苏
    1
    2
  • if !req.Task.Reload { ... } // 这里我们为任务 Task 引入了一个新的字段 Reload,标识当前任务的网页是否可以重复爬取。如果不可以重复爬取,我们需要在失败重试前删除 Visited 中的历史记录。 这里逻辑是不是反了?如果能重复爬,才需要再重新调度之前删掉记录吧。
    2023-01-13归属地:浙江
  • 翡翠虎
    用哈希表结构有什么好处?这样的话是不是就显得单机了?如果用类似redis这样的存储,加上布谷鸟算法,能够做到既省空间又支持多机协同,会不会更好?
    2022-12-20归属地:广西
    1
收起评论
显示
设置
留言
4
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部