3、数据采集技术:API采集、日志采集、传感器采集、爬虫采集的实战对比与选型
数据采集,说白了就是数据融合的「水源」。水源不干净,后面整个管道都得堵。我这些年做过的融合项目,踩坑最多的往往不是算法多复杂,而是数据怎么稳定地、合规地、高效地拿到手。
今天咱们就把四种主流采集方式掰开揉碎聊一聊。API、日志、传感器、爬虫,每种都有它的脾气。
3.1 API采集:最优雅,但最看人脸色
API采集是我个人最偏爱的方式。为什么?因为它规范。接口文档写清楚了,你传什么参数,它返回什么结构,清清楚楚。
我在一个智慧城市项目中,需要对接气象局的实时数据。对方提供了RESTful API,返回JSON格式。代码写起来很舒服:
import requests
import json
def fetch_weather_data(api_key, city_code):
url = f"https://api.weather.gov.cn/v1/real-time"
params = {
"key": api_key,
"city": city_code,
"format": "json"
}
try:
resp = requests.get(url, params=params, timeout=5)
resp.raise_for_status()
return resp.json()
except requests.exceptions.RequestException as e:
print(f"API请求失败: {e}")
return None
# 调用示例
data = fetch_weather_data("your_api_key", "101010100")
但这里有个坑——API的限流和鉴权。我曾经遇到过对方接口突然加了频率限制,每秒只能请求5次。我们的数据管道直接崩了。所以,做API采集时,一定要做好重试机制和熔断策略。
3.2 日志采集:数据量最大,但最脏
日志采集,嗯,这是我最头疼也最离不开的方式。说它头疼,是因为日志格式千奇百怪;说离不开,是因为很多系统只有日志这一种数据出口。
我记得有个电商项目,需要分析用户行为。业务方说「我们有完整的埋点日志」。结果一看,日志文件里混杂着debug信息、堆栈异常、甚至还有乱码。那段时间我天天跟正则表达式较劲。
常用的日志采集工具有Filebeat、Flume、Logstash。我一般这么用:
# Filebeat配置示例
filebeat.inputs:
- type: log
enabled: true
paths:
- /var/log/app/*.log
multiline.pattern: '^\d{4}-\d{2}-\d{2}'
multiline.negate: true
multiline.match: after
output.kafka:
hosts: ["localhost:9092"]
topic: "app-logs"
这里有个关键点——日志的时序性。日志文件是按时间滚动的,采集时一定要保证顺序,否则后面做时间窗口聚合就全乱了。
3.3 传感器采集:实时性最高,但硬件坑多
传感器采集,说白了就是物联网那套东西。温度、湿度、振动、电流……这些数据的特点是:频率高、格式简单、但噪声大。
我在一个工业互联网项目中,需要采集车间设备的振动数据。传感器每秒输出1000个采样点,通过MQTT协议上报。代码大概长这样:
import paho.mqtt.client as mqtt
import json
def on_message(client, userdata, msg):
try:
payload = json.loads(msg.payload.decode())
# 解析传感器数据
sensor_id = payload["id"]
value = payload["value"]
timestamp = payload["ts"]
# 写入时序数据库
write_to_tsdb(sensor_id, value, timestamp)
except Exception as e:
print(f"解析失败: {e}")
client = mqtt.Client()
client.on_message = on_message
client.connect("mqtt-broker.local", 1883, 60)
client.subscribe("sensors/#")
client.loop_forever()
传感器采集最大的问题是数据漂移和丢包。硬件设备受环境影响,经常出现异常值。我建议在采集层就做一次简单的滤波,比如中值滤波或限幅滤波,别把脏数据直接丢进融合管道。
3.4 爬虫采集:最灵活,但合规风险最高
爬虫采集,嗯,这是个灰色地带。我一般只在两种情况下用爬虫:一是对方没有提供API,二是需要采集公开的、非敏感的数据。
爬虫的技术栈很成熟了。Scrapy、Playwright、Selenium,各有各的适用场景。我习惯用Scrapy做大规模采集:
import scrapy
class DataSpider(scrapy.Spider):
name = "data_spider"
start_urls = ["https://example.com/data"]
def parse(self, response):
# 提取数据
for item in response.css("div.data-item"):
yield {
"title": item.css("h3::text").get(),
"content": item.css("p::text").get(),
"url": response.url
}
# 处理分页
next_page = response.css("a.next::attr(href)").get()
if next_page:
yield scrapy.Request(url=next_page, callback=self.parse)
但爬虫有个致命问题——反爬和稳定性。对方随时可能改页面结构、加验证码、封IP。我建议爬虫只作为「补充手段」,不要把它当成核心数据源。
3.5 四种方式的对比与选型
说了这么多,到底怎么选?我整理了一张对比表,你一看就明白:
| 维度 | API采集 | 日志采集 | 传感器采集 | 爬虫采集 |
|---|---|---|---|---|
| 数据格式 | 结构化(JSON/XML) | 半结构化(文本) | 数值型(时序) | 非结构化(HTML) |
| 实时性 | 高(秒级) | 中(分钟级) | 极高(毫秒级) | 低(小时级) |
| 数据量 | 小到中 | 极大 | 大 | 中到大 |
| 稳定性 | 依赖对方服务 | 高(本地采集) | 中(硬件故障) | 低(反爬风险) |
| 合规风险 | 低(有协议) | 低(自有系统) | 低(自有设备) | 高(需谨慎) |
| 开发成本 | 低 | 中 | 高(硬件对接) | 中 |
选型时我一般遵循这个原则:能用API就别用爬虫,能用日志就别自己写采集。说白了,就是优先选择最稳定、最合规的方式。
3.6 知识体系总览
下面这张图,是我对数据采集技术选型的整体理解。你可以把它当成一个决策地图:
你看,选型其实没那么复杂。核心就是搞清楚你的数据从哪里来、要到哪里去、中间有什么约束。我个人的习惯是:先评估合规性,再看实时性,最后考虑成本。顺序别搞反了,否则后面全是坑。