crawlergo 动态爬虫源码学习
优采云 发布时间: 2022-05-08 05:00crawlergo 动态爬虫源码学习
crawlergo是一个使用chrome headless模式进行URL收集的浏览器爬虫。它对整个网页的关键位置与DOM渲染阶段进行HOOK,自动进行表单填充并提交,配合智能的JS事件触发,尽可能的收集网站暴露出的入口。内置URL去重模块,过滤掉了大量伪静态URL,对于大型网站仍保持较快的解析与抓取速度,最后得到高质量的请求结果集合。
crawlergo 目前支持以下特性:
* 原生浏览器环境,协程池调度任务
* 表单智能填充、自动化提交
* 完整DOM事件收集,自动化触发
* 智能URL去重,去掉大部分的重复请求
* 全面分析收集,包括javascript文件内容、页面注释、robots.txt文件和常见路径Fuzz
* 支持Host绑定,自动添加Referer
* 支持请求代理,支持爬虫结果主动推送
Github:
作者开源了源码,我是很兴奋的,以前也有写一个的想法,但是开源的动态爬虫不多,看了其中几个。
调研
1.
•递归dom搜索引擎•发现ajax/fetch/jsonp/websocket请求•支持cookie,代理,ua,http auth•基于文本相似度的页面重复数据删除引擎
•根据文本长度
•simhash
•else
•ShinglePrint
•主要代码是python调用puppeteer,但是核心逻辑在js里
2.
•一个操作chrome headless的go库•它比官方提供的chrome操作库更容易使用•有效解决了chrome残留僵尸进程的问题
3.
•通过一些通用接口获取url信息
4.
•Web静态爬虫,也提供了一些方法获取更多URL
5.
1.rad虽然没有开源,但是它里面使用yaml进行的配置选项很多,通过配置选项可以大致知道它的一些特性。2.可以手动登陆3.启用图片4.显示对爬取url的一些限制
1.不允许的文件后缀2.不允许的url关键字3.不允许的域名4.不允许的url
5.设置下个页面最大点击和事件触发Crawlergo
之前也想过写一个动态爬虫来对接扫描器,但是动态爬虫有很多细节都需要打磨,一直没时间做,现在有现成的源码参考能省下不少事。
主要看几个点
•对浏览器 JavaScript环境的hoook
•dom的触发,表单填充
•url如何去重•url的收集
目录结构
├─cmd<br style="box-sizing: border-box;" />│ └─crawlergo # 程序主入口<br style="box-sizing: border-box;" />├─examples<br style="box-sizing: border-box;" />├─imgs<br style="box-sizing: border-box;" />└─pkg<br style="box-sizing: border-box;" /> ├─config # 一些配置相关<br style="box-sizing: border-box;" /> ├─engine # chrome相关程序<br style="box-sizing: border-box;" /> ├─filter # 去重相关<br style="box-sizing: border-box;" /> ├─js # 一些注入的js<br style="box-sizing: border-box;" /> ├─logger # 日志<br style="box-sizing: border-box;" /> ├─model # url和请求相关的库<br style="box-sizing: border-box;" /> └─tools # 一些通用类库<br style="box-sizing: border-box;" /> └─requests<br style="box-sizing: border-box;" />
根据源码的调用堆栈做了一个程序启动流程图
配置文件
pkg/config/config.go定义了一些默认的配置文件 <p>const (<br style="box-sizing: border-box;" /> DefaultUA = "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.0 Safari/537.36"<br style="box-sizing: border-box;" /> MaxTabsCount = 10<br style="box-sizing: border-box;" /> TabRunTimeout = 20 * time.Second<br style="box-sizing: border-box;" /> DefaultInputText = "Crawlergo" // 默认输入的文字<br style="box-sizing: border-box;" /> FormInputKeyword = "Crawlergo" // form输入的文字,但是代码中没有引用这个变量的<br style="box-sizing: border-box;" /> SuspectURLRegex = `(?:"|')(((?:[a-zA-Z]{1,10}://|//)[^"'/]{1,}\.[a-zA-Z]{2,}[^"']{0,})|((?:/|\.\./|\./)[^"'>