为了给wordpress的ripro主题资源站填充数据,我用golang开发了并发版爬虫和分布式爬虫两个版本,已经顺利跑通!

2023-10-10
9分钟阅读时长

为了给ripro主题资源站填充数据,我用golang开发了并发版爬虫和分布式爬虫两个版本,已经顺利跑通!代码总量还是比较多了,具体课程中再详细讲解,这篇文章主要分享一下自己的技术选型思路,以及我觉得做这个项目过程中自己的一些感悟!包括对于系统架构的理解以及对于golang语言本身的理解。

先说自己的业务选型思路,由于自己几套系统都已经上线,所以填充数据又成了棘手的问题,我以前的文章中也分享过我使用爬虫的经历,这次准备不走老路了,也不用golang系的口碑不错的colly了,而是自己来实现一套爬虫。这样做的目的有两个,一是我现在上线的站点确实需要填充数据,因为用了wordpressripro主题,资源类站点嘛,口碑和业务闭环实现不错的主题,可选的并不多,目的还是要放我自己的课程上线,但是我自己的课程暂时也就几个,数量不太够,网站空空的,感受总是不好的,所以还是找些数据来填充。二是爬虫其实是一个对于综合能力考察比较全面的项目,并且如果自己不使用现有框架,而完全从零来实现,会考察你各方面的能力。往基础点说就是你对golang语言的掌握,http协议的理解(ip代理池、隧道代理、防爬、反爬等),往业务层面上靠,可以把方方面面的知识都揉进来,比如说数据存储、高并发架构、分布式架构、各种业务中间件的使用,总之,它是特别考验一个人综合能力的,也正因如此,我准备出的课程,就是教大家具有这方面实践的能力,那既然要录课,自己不亲手实现出来也说不过去,基于这两个原因,并发版和分布式版本的爬虫就诞生了。

这过程中解决了很多意想不到的问题,比如说匹配页面时候,golang中正则表达式的理解程度,很大程度上决定了你爬虫fetcher层的业务执行效率。还是拿我使用过的python系的scrapy来做对比,因为scrapy使用过程中基本都是聚集式爬虫的开发,针对特定站点,所以我基本都用xpath,直接chromeF12模式获取xpath地址,直接填上去就可以,这样虽然简单,但是xpath的执行效率很低,如果遇到比较复杂的dom结构显然这是拖后腿的环节,还有更早期使用比较多的BeautifulSoup之类的,那个执行效率就更加低。css选择器也是类似,另外一个原因是这些工具的使用,其实不需要太多思考,如果长此以往用工具重复每天做相同的事,那么对于个人能力的成长想必也是没有助益的。因此,从效率和拓展知识边界两方面思考,我都决定使用xpath作为自己的dom解析器,当然这其间趟了很多坑,举几个例子:

  1. golangregexp这个正则package是不支持perl syntax(pcre)正则表达式的

如果正则用的少,或者没有匹配过很复杂的页面结构,那么前向断言、后向断言这些东西就应该没有用过。而有些页面内容的获取,用这种方式就效率其高。那怎么让golang支持这些功能呢?肯定也不需要重复造轮子了,已经有了一个regexp2,它可以支持你在golang代码中使用前向断言、后向断言。

  1. 修饰符的使用

在大块源代码中,如果以于修饰符的理解不深刻,很难更高效的做内容提取。比如sm就是我使用最多的两个修饰符(?sm)加到正则表达式的前面,代表着匹配内容时允许`n行以及进行多行匹配。而对于修饰符i,做英文处理时可能出镜率更高,我这次业务中没有遇到,但是U,也就是非贪婪匹配,在你把抓取数据框定到一个源码范围内,进一步做抓取,而抓取的有效内容有重复结构出现的时候,你要指定这个修改符,才可以把源码块中重复的部分全部匹配到,再通过findAllSubmatch中分组的定义,可以把你想拿的图片地址呀,url地址呀等有效信息遍历取到,方便回放到调度器中,交由多channel组成的worker`进一步处理。

  1. 页面编码的问题

这个有些站点可能会遇到,有些遇不到,要实现编码检测,再进一步做数据提取。

关于golang也有很多新的理解,如果框架用久了,或者在公司天天写业务代码,你可能不会太关注一些golang设计精妙的地方,比如说golang对于interface的定义,比如说golang中那句经典的“不要通过共享内存去通信,而要通过通信去共享内存”。展开说一下这两点,golang的接口是由使用者定义,如果你写过php或者java的话,接口就是用来规范业务实现的,接口定义什么,你就实现什么,定义了几个接口,并且你业务中有涉及,那你几个接口中的方法你就都需要实现出来,而golang中的接口有点不一样,比如说a接口有方法bcdx接口有方法y,如果你在某个文件中把这两个接口的4个方法(bcdy)都实现了,你实际就已经实现了ax两个接口,而所提的这某个文件,你搞些其他逻辑进来也是可以了。再来说另一点就是经典的这句话,如果你对于channel不怎么使用的话,那你可能也不理解这句话的深层含义,因为在golang中函数和channel都是一等公民,什么叫一等公民,就是你可以为所欲为,其它不强调,但强调一点函数和channel都可以作为struct的参数、返回值,这就极大扩展了你写程序的灵活性,顺着这个思路来想,你只要参数或者返回值是函数的时候,由于有闭包函数的存在,其实在函数里套无限多的业务逻辑都是可以的,而channel同样作为一等公民,channel中的数据结构也函盖了golang支持的所有类型,就包括了函数,普通的业务,如果只需要业务类型抽象成队列,那么channel就可以搞定,利用channel的写入和消费属性,你基本上不用第三方业务中间件(rabbitmqrocketmqredis),你也可以实现这些中间件可以做的事(话虽如此,术业有专攻,该选什么还选什么),这种灵活性就有点变态了。而channel结合着函数作为一等公民,又怎么理解呢?毕竟两个一等公民就是强强联合了,在做分布式系统中很多业务相互之间的衔接可能参数比较复杂,那么,普通的数据类型可能就无法支持一些功能,而channel加上函数共同作用,就可以传递非常复杂的rpc参数,让分布式业务之间的调度和融合显得游刃有余,总之,golang的高级技巧如果你不做复杂的项目,不做深度使用函数一等公民特性,不做channel一等公民特性的项目,应该是没啥深刻体会的,特别是天天写业务代码。

我还记得我在写公司的建店项目的时候,毕竟业务体量放那里业务复杂度自然跟自己之前做的业务不是一个量级,由此可以欣赏很多大拿的“精湛”技艺,那个时候对于golangdao扩展包大家代码写的飞起的样子记忆犹新,有人用golangmysql基础库,有人有gorm,有人用其它的数据库组件,拼mysql的方式神乎其神、各有千秋,当时觉得这个牛逼,现在来看,其实这些技巧还是术层面的,具有可习得性,类似于你看我的抖音,今天学习了一个泡妞技巧,明天学习了一个泡妞技巧,但是跟妹子一聊天一约会,你发现你撩不动她,甚至几句话聊死冷场,女生当场黑脸,一个手起刀落,你就进了黑名单!本质原因就是你没有一套成型的思想体系,没有一套真正落地实践有效的架构,而架构的习得是有门槛的,不是说不能学会,但是就算全部给你讲了,还是要看人悟性的,悟性高了,可能很快掌握,悟性不高,可能你反反复复学习也不得门径。就比如报我两性情感课的学员,我把聊天的架构节奏步骤都告诉他们了,一样有人三个月现在泡妞风生水起,而有人依旧默默无名,原地踏步。但是凡是就怕用心二字,但是只用心,只在大脑中模拟是没个卵用的,你必须身体力行,疾速实践,不然天赋的愚钝加上后天的不够努力,将让你跟老天爷赏饭吃型选手、或者能迅速抓住问题本质然后持之以恒的学习实践选手间的差距越来越大!

扯远了,扯回来,总之golang的很多高级特征,如果你自己不实际做几个项目,不做完项目好好复盘,其实你对我讲了些啥想必一定是糊涂的,这大概也是通过报名我的课程,来实现技术层面和跟女生互动层面双丰收的一大理由吧!哈哈!

圆回来,继续说回我开篇埋的坑,最后一个,就是对于系统架构的理解。很多业务现在看来是不需要架构的,就比如说你做的流量站,就是靠联盟广告收入来赚钱,你也没啥野心,现在短视频时代,留给web的红利越来越少了,所以能端好手上的饭碗就不错了,还要啥自行车,所以这种网站甚至云原生那一套都不需要用,就cvm或者轻量级服务系统上直接编译安装程序、业务中间件、逻辑中间件,然后狠劲搞流量就完了。架构对于什么类型的企业作用最大呢?我觉得就是提高了每个人的效能,便能使整体效能达到指数级的提高,类似于下面这张图:

这也就是为什么现在都搞云原生的原因,一个分布式系统的部署,我在传统机器上也可以搞,我之前scrapy引入scrapy-redis作为数据中间件,我就可以把各种机器的闲置性能全部利用起来,达到最大化榨干服务器性能的目的。而这个东西你传统企业也可以搞呀,我做多机房部署,搞几个运维,在那源码安装也一样可以完成呀,为啥现在都要上云原生呢?就是因为云原生相关的组成部分,可以解放很多人力的投入,并且可以让scrum真正的得到落地。至于技术架构,我觉得没有最好的,只有更适于当前情况的架构,所以无所谓最好的架构,最牛逼的架构。

但是基于k8s的云原生开发的技能,我倒觉得是现在大厂程度员,或者有志于进大厂的程序员都应该具备的一项技能。

这作为一个引子,开始进入我的广告时间,如我开篇所说,因为这是一套完整的系统,有并发式和分布式两个版本,是用golang语言开发的,没有引入任何第三方框架的一套爬虫系统,通过这套系统的搭建,你基本上在golang语言掌握方面,就比其他人高出不指一个数量级,因此我觉得购买这套课程,然后认真敲代码,认真学习,你的竞争实力将继续水涨船高一波。你以为这就完了?在这过程中会把k8s云原生的东西给你讲懂讲透,涉及到的东西,可以看这里,也就是说架构师云原生强化课程的全部内容,加上今天我这篇文章所讲的这个用golang开发的,带有并发和分布式两个版本的爬虫系统,是我即将录制课程的核心组成部分。不同于传统的讲法,过程中我会把涉及到的python系的爬虫框架也拿来对比,让你掌握golang的同时,通过语言间的对比,让知识的吸收更加高效!现在录制课程已经开始立项了,我也在备课了,后面我会把这套系统开发的全部流程录制视频(包括golang的基础部分),其实应该早就开始的,但是之前买的采集卡声音图像不同步我给退了,事情就搁置了一段时间,这次买了圆钢的GC553,等到货后就开始交付,欢迎加入我的课程。


下面课程销售中,欢迎按需购买:


架构师云原生强化课程
彻底学会pythongolang系统化课程
我广告部分说的其实就是上面这两门课程的合集,这个golang爬虫系统是3大实战项目中的一个。
艾森聊天课程
艾森私教门徒课程

本主题指南

技术实践与开发文档
Avatar

Aisen

Be water,my friend.
  • 使用golang部署运行tls的https服务时,不用停机,高效证书下放,如何实现?

    在网络通信中,HTTP和HTTPS是常用的应用层协议,而四层服务传输协议和七层服务传输协议则是不同的协议模型。当使用 golang 语言部署和运行带有 TLS 的 HTTPS 服务时,需要采取一些技巧来实现高效证书下放,而不会影响线上服务的正常运行。 HTTP和HTTPS是两种不同的应用层协议,HTTP协议是未加密的、明文传输的,而HTTPS是基于TLS/SSL协议的安全版本,通过加密与认证保护数据传输的安全性。在实际应用中,为了保护用户信息的安全,通常使用HTTPS协议进行网络通信。 四层服务传输协议和七层服务传输协议是不同的协议模型,分别定义了网络通信的逻辑结构和规则。四层服务传输协议(如TCP和UDP)负责在不同主机之间建立端到端的通信连接,并提供可靠的数据传输、流量控制等功能;而七层服务传输协议(如HTTP、SMTP、FTP等)定义了应用程序之间的通信规则、格式和内容,提供特定的服务功能。 Golang是一门开源的编程语言,具有高效性能和良好的并发处理能力。在使用Golang部署和运行TLS的HTTPS服务时,可以采用一些技巧来实现高效证书下放,而不会影响线上服务的正常运行。比如通过使用ACME协议自动化管理证书、使用GRPC框架进行交互式的证书下载等方式,可以有效解决证书下放的问题,并提高系统性能和可靠性。 综上所述,HTTP、HTTPS、四层服务传输协议、七层服务传输协议、Golang、Go语言学习以及Go语言技巧都是网络通信和编程中非常重要的概念和关键词。在进行相关学习和实践时,需要注重理解和掌握这些内容,才能更好地应对实际需求和挑战。

  • 你所不知道的golang高级用法
  • 在aws上以lambda方式部署golang应用 -(上)用.zip压缩文件部署Go Lambda functions

    在使用 AWS Lambda 运行 Go 时,可以将代码打包成 .zip 文件并上传到 Lambda 上。这样做的好处是可以将所有的依赖项打包在一个文件中,而不需要在 Lambda 中安装它们。同时,也可以避免在多个文件之间进行部署和管理的复杂性。 要将 Go Lambda 函数打包为 .zip 文件,您需要将函数代码和依赖关系放置在一个文件夹中,并将其压缩为 .zip 格式。如果您的 Go 程序包含外部依赖项,则需要在函数代码中包括它们,或者将它们一起打包到 .zip 文件中。 一旦您已经打包了 Lambda 函数,就可以通过 AWS 控制台或 AWS CLI 将其上传到 Lambda。上传完成后,您可以测试该函数并将其发布到您的应用程序中。通过使用 .zip 文件打包 Lambda 函数,可以有效地简化部署和管理过程,使您的开发工作更加高效。

  • 夯实基础的go语言简明学习手册