学习目标
跟随架构师律师马原的脚步读完这一讲,你能:
- 区分原始数据、结构化数据和分析结果的法律属性
- 理解"实质性投资"在司法实践中的含义
- 评估自己的数据产品的"增值度"和法律风险
技术原理
数据在技术层面可以分成三层:
Layer 1: 原始 HTML
↓ parse
Layer 2: 结构化数据 {title: "...", author: "...", content: "..."}
↓ process
Layer 3: 分析结果 "该作者近30天平均阅读量 1500,环比增长 20%"
Layer 1 - 原始 HTML
这是服务器返回的原始字节流。它可能包含 CSS、JavaScript、图片链接、广告代码。法律上,HTML 本身可能受著作权保护(如果其编排具有独创性),但通常不保护。
Layer 2 - 结构化数据
从 HTML 中提取的字段。比如从测试网站文章页提取:标题、作者、发布时间、阅读量、点赞数、标签。这些数据本身通常不享有著作权——它们是事实信息,不是独创性表达。
Layer 3 - 分析结果
对结构化数据进行统计、建模、分析后的输出。比如"2024年测试网站前端领域十大热门话题"、"某技术栈的采用率趋势报告"。这一层通常享有著作权(作为文字作品),也可能构成商业秘密。
关键问题:你在哪一层使用数据,决定了法律风险。
真实判例
大众点评诉百度案
百度抓了大众点评的用户点评,展示在百度地图里。技术上,百度做的是 Layer 1 → Layer 2 的转换:从 HTML 提取点评内容,展示在自己的产品里。
法院认定:这种行为"实质替代了大众点评网向用户提供信息"。用户不需要去大众点评,在百度地图里就能看到全部点评。
赔偿:300万元经济损失 + 23万元合理费用。
抖音诉刷宝案
刷宝 APP 用爬虫抓取抖音的短视频、用户信息、用户评论,直接搬运到自己的 APP 上。技术上也是 Layer 1 → Layer 2,然后原样展示。
法院认定:构成不正当竞争。赔偿500万元。
法院特别指出:
"抖音平台针对上述非独创性数据的收集、存储、加工和传输进行了实质性的投资,因此抖音平台对非独创性数据的集合应该具备合法权益。"
"实质性的投资"是这里的关键词。法院保护的不是"数据"本身,而是"获取和整理数据的劳动"。
微博诉蚁坊案
蚁坊从微博抓取用户数据,用来做舆情分析服务。技术上,蚁坊做的是 Layer 2 → Layer 3:抓取原始数据后,进行分析加工,输出报告。
法院仍然认定构成不正当竞争。但注意:这个案子的判决逻辑和大众点评案不同。蚁坊不是在"原样展示"数据,而是在"利用数据做竞争业务"。法院认为,微博的数据生态是微博投入大量成本建设的,蚁坊直接抓取这些数据去卖钱,是"搭便车"。
法律分析
中国目前没有专门的数据权属法。民法典第127条留了白:"法律对数据、网络虚拟财产的保护有规定的,依照其规定。"——但至今没有"规定"出来。
司法实践中,数据保护主要通过三条路径:
路径一:反不正当竞争法
保护的是"竞争利益",不是"数据所有权"。要点:
- 原告对数据有实质性投资
- 数据能给原告带来竞争优势
- 被告的行为构成"搭便车"或"实质性替代"
路径二:著作权法
如果数据集合的编排具有独创性(比如数据库的筛选、排序、注释),可能构成汇编作品。但大多数爬虫抓取的原始数据不满足独创性要求。
路径三:商业秘密
如果数据是不公开的、有商业价值、原告采取了保密措施,可能构成商业秘密。但爬虫通常抓的是公开数据,商业秘密保护不适用。
2025年修订的《反不正当竞争法》第13条新增:
"经营者不得以欺诈、胁迫、避开或者破坏技术管理措施等不正当方式,获取、使用其他经营者合法持有的数据,损害其他经营者的合法权益,扰乱市场竞争秩序。"
这个新条款把"不正当获取数据"明确列为不正当竞争行为,不再需要用第2条"一般条款"来兜底。
实战输出:数据产品增值度自评表
"""
数据产品增值度自评表
评估你的数据处理到了哪一层,法律风险在哪个档
"""
class DataProductAssessor:
def __init__(self, product_description):
self.desc = product_description
self.layer = 0
self.risk = 'low'
def assess_layer(self, features):
"""
评估数据加工层级
features: 产品功能特征列表
"""
layer_1_signs = ['原始展示', '全文复制', '镜像', '聚合']
layer_2_signs = ['结构化', '分类', '标签', '索引']
layer_3_signs = ['分析报告', '趋势预测', '模型', '算法推荐']
l1 = sum(1 for f in features if any(s in f for s in layer_1_signs))
l2 = sum(1 for f in features if any(s in f for s in layer_2_signs))
l3 = sum(1 for f in features if any(s in f for s in layer_3_signs))
if l1 > l2 and l1 > l3:
self.layer = 1
self.risk = 'high'
elif l2 > l3:
self.layer = 2
self.risk = 'medium'
else:
self.layer = 3
self.risk = 'low'
return self.layer
def assess_substitution(self, factors):
"""
评估是否构成"实质性替代"
factors: {
'user_stays_on_platform': False, # 用户是否留在你的平台
'shows_full_content': True, # 是否展示全文
'no_attribution': True, # 是否标注来源
'same_service_type': True, # 是否提供同类服务
}
"""
score = 0
if not factors.get('user_stays_on_platform', True):
score += 30
if factors.get('shows_full_content', False):
score += 25
if factors.get('no_attribution', False):
score += 20
if factors.get('same_service_type', False):
score += 25
if score >= 70:
print("🔴 高概率构成'实质性替代'")
elif score >= 40:
print("🟠 可能构成'实质性替代'")
else:
print("🟡 替代风险较低")
return score
def report(self):
print(f"\n=== 数据产品风险评估: {self.desc} ===")
print(f"加工层级: Layer {self.layer}")
print(f"基础风险等级: {self.risk}")
if self.layer == 1:
print("\n⚠ 建议:")
print(" 1. 避免全文展示原始内容")
print(" 2. 增加数据加工和分析环节")
print(" 3. 明确标注数据来源")
print(" 4. 考虑转型为'分析服务'而非'聚合平台'")
# 使用示例
assessor = DataProductAssessor('我的数据聚合APP')
assessor.assess_layer(['聚合展示', '全文复制', '结构化存储'])
assessor.assess_substitution({
'user_stays_on_platform': True,
'shows_full_content': True,
'no_attribution': False,
'same_service_type': True,
})
assessor.report()