Home
avatar

.𝙃𝙖𝙣

为了准备 LoRA 数据集,我第一次用爬虫批量下图

最近想自己试一下训练 LoRA,但卡得很现实:数据集不够。

一开始我还想着手动下,后来下了十几张就受不了了。恰好这段时间在学Python,发现这事如果不借助代码,基本做不下去。所以这篇先记一下这段时间正经使用Python时的思路变化:从想逆接口,到逆不出来,再到最后老老实实开浏览器,模拟手动翻页,在 DOM 里拿图像地址去下载。

1. 起因很简单:想训 LoRA,但手动下载太慢了

这段时间找了一个底模,稳定性很好。工作上业务需要多风格,只能去训练 LoRA。

但训练这件事,说到底还是要先准备数据集。这个问题一落到手上,我最先碰到的不是训练参数,而是最基础的一件事:

图不够,而且手动下载太慢。

刚开始我还觉得这事应该不复杂。

无非就是:

  • 打开网页
  • 一张张翻
  • 一张张保存

但真试了以后,很快就发现不对。

因为一旦数量上来,手动操作会特别机械,前面少量搞一搞还行,真要为训练准备一批像样的数据,这种方式效率太差了。

所以问题很快就变成了:

能不能直接把网页里的图批量拿下来?

正好试试这段时间学的Python,这也算是我第一次带着很明确的目标去碰“爬虫”这个东西。

2. 我一开始想走的路,是先逆接口

最开始我对爬虫的想象还挺直接的。

我会觉得,既然网页上的图片最后总得从某个接口回来,那最理想的做法当然是:

  • 找到接口
  • 把请求参数抄下来
  • 直接请求数据
  • 再把图片地址取出来下载

这个思路看起来很对,而且也比较“程序员”。

所以我在家那几天,主要就是在看网页请求,想试着把它逆出来。

那时候我做的事情基本就是这些:

  • 打开开发者工具看 Network
  • 看翻页时发了哪些请求
  • 看返回体里有没有图片地址
  • 看请求参数是怎么带的
  • 看 headers、分页参数、时间戳这些东西有没有规律

我一开始还挺有期待,觉得只要把接口盯住,后面就顺了。

结果实际试下来,并没有我想得那么简单。

3. 接口我不是完全没看到,是“看到了也没真正拿下来”

这个地方我得先记一下,不然后面容易把事情说得太轻松。

我不是完全没看到请求。

问题是:看见请求,不等于你就能顺利把它复现出来。

我当时碰到的难点主要在这几类:

  • 请求参数不止明面上的分页信息
  • 有些值看起来像是动态生成的
  • 页面行为和接口触发不完全是一一对应的
  • 有些请求就算抄出来了,自己发也不一定拿到同样的结果

说白了就是,我能感觉到这条路是对的,但以我现在的水平,还没法把它稳定复现出来。

这个阶段挺消耗人的,因为它会让你反复停在这种状态里:

  • 感觉快摸到了
  • 但就是差一口气
  • 改一下参数还是不行
  • 再试一下请求头也不行

我后来慢慢接受了一个现实:

这条路我不是完全学不会,而是至少在现在,不适合作为我先解决问题的第一条路。

这点对我其实挺重要。

因为它让我第一次比较明确地意识到:

技术上“最优雅”的方案,不一定是当前最适合我的方案。

如果我一直卡在逆接口这件事上,业务需求就要超时了,别人都在等着我。

4. 接口走不通以后,我开始换思路:先别追求优雅,先把图拿下来

我后来给自己换了一个目标:

先别管是不是最漂亮的爬法,先把这件事做成。

既然网页本来就能正常展示图片,说明至少有两件事已经成立:

  1. 浏览器能把页面翻下去
  2. 页面里最终能出现我要的图片地址

那我就不一定非得先把底层接口完全啃下来。

我完全可以换一种更笨、但更接近人工操作的办法:

  • 直接开一个浏览器
  • 让脚本去模拟翻页
  • 每翻一页,就从 DOM 里找图片地址
  • 找到地址以后再去下载

这个思路一出来,整件事一下就落地多了。

因为它把问题从“我能不能先逆明白接口”换成了:

  • 我能不能让页面自动翻
  • 我能不能从页面元素里把地址取出来
  • 我能不能把这些地址批量存下来

这三件事,至少都比逆接口更贴近我当时能做的范围。

5. 这次我第一次真正开始理解:DOM 不是前端专属词,它对爬虫也很关键

以前我对 DOM 这个词的印象,其实更多还是“网页结构”。

但这次开始碰这种浏览器模拟方案以后,我才比较实际地感觉到:

DOM 对爬虫来说也非常重要。

因为我最后不是去接口里直接拿数据,而是去页面上找已经渲染出来的内容。

这件事一旦落到代码里,核心就变成了:

  • 这一页的图片元素在哪
  • 图片地址是在 src 里,还是在别的属性里
  • 翻页之后,DOM 什么时候更新
  • 什么时候取值最稳

我不再只是“看网页”,而是开始把网页当成一棵可以被脚本读取的结构树。

这个理解对我帮助挺大。

因为它把我前面学 Python 时那些零散概念,第一次往一个真实场景里接上了。

6. 后面我的做法其实不复杂:模拟手动翻页,然后从 DOM 把地址拿出来

我最后走通的方案,核心逻辑其实挺朴素的。

第一步:启动浏览器

先让程序把目标网页打开,而不是自己手动一点点操作。

第二步:模拟人工翻页

这一点很关键。

因为我要的图片不是一开始就全在第一页里,所以程序不能只打开一次页面就结束,而是得像人一样往后翻。

第三步:等页面内容更新

翻页以后不能立刻拿数据,不然很容易拿到旧内容或者空内容。

所以这一步我当时也开始慢慢意识到:

  • 浏览器自动化不是“点了就算完成”
  • 页面有没有真正更新,要等
  • 有时候还得判断某个元素是不是已经出现

第四步:从 DOM 里取图像地址

这一层才是真正开始拿数据。

我当时的重点不是复杂解析,而是先把这几件事确认清楚:

  • 图片标签到底在哪
  • 地址是不是已经出现在属性里
  • 一页里能取多少张
  • 有没有重复

第五步:把地址下载下来

拿到地址以后,后面就简单很多了。

这一步至少比前面的“逆接口”阶段踏实,因为地址已经是实打实能用的结果了。

整个方案看起来不高级,但很适合我当时的状态。

因为它绕开了我暂时还啃不动的地方,先让我把事情做成了。

7. 这件事对我最大的提醒是:先做成,比一开始就追求最优方案更重要

如果只从“技术洁癖”的角度看,这次的方案肯定不是最优雅的。

最优雅的路径,还是应该把接口逆明白,直接请求数据。

但问题是,当时的我还没有那个能力稳定做到。

如果一直死磕那条路,很可能最后什么都没落下。

这次让我比较有感触的一点就是:

解决问题的时候,先判断自己当前能打哪一层。

我现在把这件事记成两个层次:

第一层:理想方案

  • 直接逆接口
  • 参数规律摸清
  • 批量请求数据
  • 结构更清晰,效率也更高

第二层:当前可做方案

  • 开浏览器
  • 模拟翻页
  • 从 DOM 里取地址
  • 先把数据集下回来

这次我最后选的是第二层。

不是因为第二层更高级,而是因为它对当时的我来说更可执行。

我现在越来越觉得,这种判断其实很重要。

8. 这篇顺手记几个我这次真正碰到的新东西

这次虽然只是为了搞数据集,但它确实让我第一次比较认真地碰到了几样以前只是听过的东西:

1)浏览器自动化

以前我会把脚本理解成“直接请求接口”。这次才发现,浏览器本身也能被程序驱动。

2)DOM 抓取

以前知道 DOM 是网页结构,这次开始把它当成数据来源看。

3)等待和时机

翻页以后不是立刻就能拿值,页面更新时机本身就是问题的一部分。

4)重复数据处理

翻页抓图时,如果不处理重复,最后很容易把同一批图反复下回来。

5)先把问题做成

这次不是最漂亮的方案,但它让我第一次有了一个完整闭环:

  • 有目标
  • 有失败尝试
  • 有方案切换
  • 最后把结果拿到

9. 先记一个阶段结论

这次为了准备 LoRA 数据集去碰爬虫,我现在先记下几个结论:

  1. 逆接口和真正复现接口,是两回事
  2. 在当前能力不够的时候,浏览器模拟 + DOM 抓取是一个很实用的兜底方案
  3. 页面上的结果,本身也可以当数据源,不一定非得先从底层接口拿
  4. 爬虫不只是“发请求”,有时候更像是在自动执行一套人工操作
  5. 先把事做成,再回头优化方案,这个顺序对我现在更合适

这篇先记到这里。

这次虽然只是为了下图,但我已经明显感觉到,Python 到了这里,它已经慢慢变成一个能帮我解决实际问题的工具了。

Python 爬虫 LoRA DOM 浏览器自动化