一个完整的采集程序需要考虑哪些
- 作者: 刘杰
- 来源: 技术那些事
- 阅读:136
- 发布: 2025-08-30 09:45
- 最后更新: 2025-08-30 09:45
数据采集脚本,相信用到的程序员不少,但是如何将目的数据采集入库。设计方案估计也是各种各样。那么一个完善的采集程序,应该涉及到哪些方面呢。这里我来抛砖引玉,提供一些思路。
我这里的场景,针对的是个人用户,服务器或者采集的电脑只有一个,ip 地址一个。也就是说,一旦被目标网站的防采集程序发现被封死ip,后边基本就结束了。。。所以,必须尽量保证,利用有限的资源,将数据抓取回来,而且还要保证不被发现。

内容采集程序构成
内容采集器,作用如其名字所示。就是将目的数据采集到本地。额,有人可能会问,采集回来这不就完事了吗,还有啥可写的。我这里说的采集,就是一个基本的采集功能,注意是基本的采集功能,这里的基本,不是说程序不够强大,而指的是采集的内容要相对全面,不要太过具体。
必须有一个强大的采集器
这里的采集器,指的仅仅是将目标url 页面数据,拿回到本地的程序。要应对各种防采集策略,采用 selenium 自动化测试工具模拟客户端进行破解。之前写过几篇关于selenium 的文章,可以去看看,或者去网上搜索下,这个策略基本可以应付任意的防采集策略。
内容采集策略
假如我目的要采集一个电商网站的内容详情的数据,比如价格,sku,评论等等。假如我们这个采集器功能够强大,比如通过 selenium 实现的,可以突破任何防采集功能的js 渲染,加密,人工验证码识别等等。采集内容的第一步就是将整个页面详情采集到本地。注意这里说的是整个目标页面。
为什么要采集整个页面,这里有几个原因。
-
页面采集的内容项目太多,且内容项的具体结构不明朗,无法做到一次采集到全部数据。
这里意思是说,假设我采集一个字典汉字的繁体字功能,首先你要了解到,一个简体字,到底对应几个繁体字呢,这个多少甚至会影响到底层数据结构的设计。
如果是简体字繁体字一一对应,那么就在主表留一个繁体的字段,设置为 char,长度为1 即可。如果是多个,可能我们可能会将繁体字段设计为一个 varchar,由于不知道长度,给一个足够长度 50。或者其他考虑多分一个表,根据一对多关系设计繁体字的关联关系。等等。
在采集过程中,底层数据结构可能会根据每次采集时候,发现的数据实际情况做出调整。而且调整不止一次。这里就产生第二个问题。
-
多次对同一网站进行大量数据采集,可能会触发网站的防采集程序
这个问题,解决方式也简单,就是尽可能少的对目标网页进行采集,比如就只有一次,次数越少,频率越低,采集量越少,越不容易被防采集程序发现。(这里不考虑,有多个ip和大量的采集客户端,一般一个人可能大多数情况就一太个人电脑,一个ip,专业做采集,各种资源足够的就不用考虑了)。我们采集整个网页,这样可以保证内容一次全抓回来,而且不用跑第二轮采集。
采集脚本必须注意点
采集过程中,注意采集频率,避免被防采集程序发现
每采集一页数据,可以根据实际情况进行sleep 几秒,具体几秒不一定,一般我们可以考虑,取 3s 以内的随机时间。由于每次请求间隔是随机的,防采集程序很难判定,你的浏览行为是采集操作。
如果采集数据比较大,注意要有进度提示
如果采集任务比较长,比如需要几小时,甚至是几天,就需要考虑有个进度提示。
最简单方式可以通过已采集量/总量 的方式,每隔一段时间,或者采集条数,就提示一次。当然这个提示不太明确,最好的方式是提供预计完成时间。这个时间,也很好得出。需要计算数据处理的速度。
$$ 预计完成时间 = 剩余数据条数 * 数据处理速度 $$
$$ 数据处理速度 = 已处理数据条数 / 已处理数据花费时间 $$
$$ 已处理数据花费时间 = 当前时间 - 任务开始时间 $$
这样,没过一段时间就能推算出预计完成时间,虽然不够准确,单页查不了多少。
如果数据量大,或者数据容易爆出问题导致程序停止,请考虑能够自动继续执行任务
任务反复停止,每次停止都要手动修改代码,让程序恢复,很烦人,最好做成自动的,每次重新启动即可继续执行。
如果有必要,可以提供一个检测进程,发现程序停止后,可以自动启动,以保证程序能够顺利执行完毕。
数据清洗
由于,之前我们定的采集策略是比较粗糙的,采集的整个页面。这里离我们准确的目标数据还差很多。我们必须对页面进行过滤,值保留目标数据。
数据清洗一般至少也需要两次,当然,如果你对你所需数据的行业非常了解,可以一次就设计出完善的底层结构。那最好的结果一次就能通过。我认为,可能大多数人做不到。
要进行数据清洗,就得有相应的清洗脚本(或者说程序),就是过滤目标数据的程序。这个程序一般情况也不是一次就能完善,好多时候,是跑到有问题的时候,必须进一步优化改良。
第一次数据清洗
根据选定的几个目标页面,完成的清洗程序,一般都不是比较完善的程序,但是必须在某些情况有异常时候,做好日志记录,这样一遍程序后,我们就能发现目前程序的不足,和底层结构的设计问题。
在一次清洗后(也可能未完成第一次清洗),去完善清洗程序,完善底层数据表的设计问题。
由于我们清洗程序是基于,上一步的粗略采集的页面数据进行的,所以可以肆无忌惮的进行反复验证,调试程序,而不会在这个过程中被目标网站发现。而且由于是基于本地数据清洗,速度会相当快,如果数据量太大,可以考虑将清洗程序做成多进程(多线程)并发程序,这样只要电脑扛得住,处理速度就快加快 N 倍。
第二次清洗
如果是完成了第一次清洗,且又根据数据的实际情况调整了数据表。第二轮清洗,可以考虑保留第一次的清洗结结果,毕竟第一次数据,只是部分数据不完善,并不是不对。数据量比较大的话,第二次处理的时候,可以针对第一次处理时候异常的数据进行。这样第二次处理还会快得更多。
如果数据总量比较少,那第一次结果,可以完全不考虑,直接删除第一次结果,直接将调整后的清洗脚本再来一次就行了。如果还有问题,还可以进行第三次第四次。
根据以上方法,很快就能将最终数据清洗完毕。
由于我们针对的是个人或者小资源量的采集场景,所以各种服务架构扩展之类的就不做考虑。如果是企业级的架构设计,很可能还涉及到自动扩缩容,等等。其实本质上也就是根据实际情况,对简单架构进行扩展而已,在多一大堆程序来辅助核心采集程序。而且往往辅助程序,有时候的代码量,比核心程序也不少。好了,以上就是个人针对一个相对完整的采集程序的一些考虑。如果有更好的思路,欢迎各位留言。