数据采集的合规边界:robots、服务条款与个人数据的三条线

先说清楚一件事

技术上的可行性不等于法律上的合规性。这两件事必须分开判断,因为代理和采集工具不会告诉你在哪一步越了界。

常见的误解是”抓公开数据不违法”。这句话既不完整也不准确:数据的公开性只是判断因素之一,还要看采集方式、数据性质、目标站点的条款,以及你所在和业务涉及的法域。

下面按三条线拆开讲,这三条线是从业者最常踩的。

第一条线:robots.txt 的法律地位

robots.txt 本身不是法律文件,它是站点表达采集意愿的一种约定。它的法律意义在不同法域差别很大:

  • 中国:主流司法实践倾向于认可 robots 协议的约束力,违反它可能被作为”未经许可”的证据之一。
  • 美国:robots 本身约束力有限,但违反明确的访问限制可能触及《计算机欺诈与滥用法》(CFAA)的争议地带。
  • 欧盟:结合数据库权利(Database Right)和 GDPR 一起判断,robots 只是其中一个因素。

可操作的判断:把 robots.txt 当作最低要求而不是合规上限。遵守它不保证合规,但违反它会让你的处境明显变差——尤其是在发生纠纷时,它是最容易被拿来当作”你明知不可为而为之”的证据。

# 抓取前先读 robots,并把这个步骤固化进流程
import urllib.robotparser as robotparser

def allowed(url: str, user_agent: str = "*") -> bool:
    from urllib.parse import urlparse
    parsed = urlparse(url)
    rp = robotparser.RobotFileParser()
    rp.set_url(f"{parsed.scheme}://{parsed.netloc}/robots.txt")
    try:
        rp.read()
    except Exception:
        return True          # robots 不可读时按允许处理,但要记录这件事
    return rp.can_fetch(user_agent, url)

注意最后那个 except:robots 读不到时默认放行是常见做法,但你应该把这个情况记录下来。事后追责时,”我尝试读过”和”我从没读过”是完全不同的两种情况。

第二条线:服务条款的约束力

服务条款(ToS)是你和目标平台之间的合同关系,约束力比 robots 明确得多。多数平台的 ToS 里有明确的禁止条款,例如:

  • 禁止自动化访问或使用爬虫
  • 禁止将平台数据用于商业目的
  • 禁止绕过技术保护措施
  • 禁止对数据做批量复制或再分发

关键点在于:注册账号即视为接受 ToS。所以如果你为了采集去注册了账号,那么 ToS 对你直接适用,这与”我抓的是公开页面”是两个层面的问题。

可操作的判断:如果你需要登录才能看到内容,那么你几乎一定已经接受了该平台的 ToS,此时”登录态采集”的风险等级远高于匿名抓取公开页面。

采集方式相对风险说明
匿名抓取公开页面较低仍需遵守 robots 与访问频率限制
携带登录态抓取直接受 ToS 约束,可能同时触发账号封禁
绕过验证码 / 付费墙很高通常被认定为规避技术保护措施
抓取后转售原始数据很高触及数据库权利与不正当竞争

第三条线:个人数据

这是唯一一条一旦越界就很难补救的线,也是最容易被技术出身的采集者忽略的。

以下内容几乎在所有主流法域都属于受保护的个人数据,不要采集

  • 姓名、手机号、邮箱、身份证件号
  • 收货地址、支付信息
  • 用户头像、昵称与账号 ID 的关联信息
  • 位置轨迹、设备标识符
  • 评论、评价中可识别到具体个人的内容
  • 健康、宗教、政治倾向等敏感信息

为什么这条最危险:其他两条线通常导致民事纠纷或账号封禁,而个人数据违规可能直接触发行政处罚,GDPR 下的罚则可按全球营业额比例计算。

可操作的判断:在写选择器之前先问一句——这个字段能不能对应到某个具体的人?如果答案是”能”,就需要有明确的法律依据(同意、合同必要、法定职责等),并且要有相应的处理规范。

实践中更稳妥的做法是在采集阶段就做数据最小化:只取业务真正需要的字段,并且在入库前剥离可识别信息。

# 采集阶段就剥离个人可识别信息,而不是事后清理
PII_KEYS = {"user_name", "phone", "email", "avatar", "user_id", "address"}

def strip_pii(record: dict) -> dict:
    return {k: v for k, v in record.items() if k not in PII_KEYS}

# 如果业务确实需要聚合结果,只保留统计量
def aggregate(records: list) -> dict:
    prices = [r["price"] for r in records if "price" in r]
    return {
        "sample_size": len(prices),
        "avg_price": sum(prices) / len(prices) if prices else None,
        "min_price": min(prices) if prices else None,
    }

聚合后的统计量通常不再属于个人数据,这是”既要数据又要合规”最常见的解法。

一个可操作的边界清单

在启动任何采集项目之前,逐项确认:

上线前合规检查

  • 已阅读并遵守目标站点的 robots.txt,且记录了读取结果
  • 确认采集是否需要登录;如需登录,已明确所适用的服务条款
  • 未绕过任何验证码、付费墙或其他技术保护措施
  • 采集字段中不含个人可识别信息;如需要,已在采集阶段剥离
  • 请求频率对目标站点的负载影响可忽略(单 IP 并发控制在低位)
  • 数据仅用于内部分析,不对外转售原始数据
  • 保留了采集时间、出口 IP 与页面的可复现记录
  • 业务涉及跨境时,已确认目标法域的具体要求

代理在这个问题里的位置

代理只解决”从哪里访问”,不解决”可不可以访问”。用住宅代理让请求看起来像真实用户,不会改变你在 ToS 和隐私法下的义务——反而可能被视为刻意规避检测,在纠纷中构成不利情节。

所以正确的顺序是:先做合规判断,再决定技术方案。反过来做,等于用技术手段给一个不该做的项目开路。

遇到具体问题时

本页提供的是通用判断框架,不构成法律意见。数据抓取的法律适用高度依赖具体案情、数据类型和涉及的法域,涉及实际商业决策时请咨询具备相应资质的专业律师。

取舍结论

维度结论
前提条件已明确目标站点是否需要登录、采集字段是否涉及个人数据、业务涉及哪些法域。
核心取舍更激进的采集方式通常能拿到更多数据,但同时把风险从”民事纠纷”推向”行政处罚”,且往往不可逆。
不适用场景需要绕过验证码或付费墙、需要采集个人数据、需要转售原始数据的项目,不应当在技术层面寻找变通做法。

一句话:先判断能不能做,再决定怎么做;代理只改变访问路径,不改变你的法律义务。

在你的目标站点上验证这套方案

文中的做法都可以用试用额度直接跑通。用你自己的目标站点测一轮,成功率数据比任何评测都可靠。