4、爬虫与数据采集:Python爬虫基础(Requests/Scrapy)、金融网站API对接、反爬策略与合规注意事项
做金融事件图谱,第一步就是搞数据。没有数据,后面那些实体识别、关系抽取全是空中楼阁。我刚开始做这个项目时,以为最难的是算法模型,后来才发现——把数据稳定、合规地拿回来,才是真正的硬骨头。
这一章,咱们就聊聊数据采集那些事。说白了,就是怎么用Python把金融网站上的信息搬回本地。我会把Requests和Scrapy这两个工具讲透,再聊聊API对接和反爬策略。嗯,合规这块尤其重要,我吃过亏,后面会细说。
4.1 Python爬虫基础:从Requests到Scrapy
我个人习惯,小规模采集用Requests,大规模工程用Scrapy。为什么?你想想看,抓几百条新闻用Requests写个脚本就够了,但要是每天监控上千个金融网站,Scrapy的异步架构能省下你大把时间。
4.1.1 Requests:轻量级爬虫利器
Requests库,说白了就是帮你发HTTP请求的。我见过不少新手用urllib,代码写得又长又丑。其实用Requests,几行代码就搞定。
import requests
# 抓取东方财富网某只股票的新闻
url = "https://finance.eastmoney.com/a/czqyw.html"
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"
}
resp = requests.get(url, headers=headers, timeout=10)
print(resp.status_code) # 200表示成功
print(resp.text[:500]) # 打印前500个字符看看结构
这里有个坑——headers一定要加。我在项目中遇到过,不加User-Agent,很多金融网站直接返回403。你想想看,服务器一看请求里连浏览器标识都没有,肯定怀疑你是爬虫。
4.1.2 Scrapy:工业级爬虫框架
当你要采集的数据量大了,Requests就有点力不从心了。Scrapy才是正解。它内置了请求调度、去重、管道存储等功能,你只需要写爬虫逻辑就行。
我记得第一次用Scrapy做金融数据采集,目标是抓取沪深两市所有上市公司的公告。如果用Requests,得写几百行代码处理并发和异常。用Scrapy,核心代码不到50行。
import scrapy
class FinanceNewsSpider(scrapy.Spider):
name = "finance_news"
start_urls = ["https://finance.eastmoney.com/a/czqyw.html"]
def parse(self, response):
# 提取新闻列表
for news in response.css("div.list-item"):
yield {
"title": news.css("a::text").get(),
"url": news.css("a::attr(href)").get(),
"time": news.css("span.time::text").get()
}
# 翻页
next_page = response.css("a.next::attr(href)").get()
if next_page:
yield scrapy.Request(url=next_page, callback=self.parse)
为什么用Scrapy?异步并发是核心优势。你想想看,Requests是串行的,发一个请求等一个响应。Scrapy基于Twisted异步框架,可以同时发几十个请求,速度能快10倍以上。
4.2 金融网站API对接
爬虫虽然好用,但有些金融数据源提供了官方API。能用API就别用爬虫——这是铁律。为什么?API稳定、合规、数据格式规范,省去了解析HTML的麻烦。
4.2.1 常见金融数据API
| 数据源 | API类型 | 特点 | 限制 |
|---|---|---|---|
| 东方财富 | HTTP REST | 行情数据丰富,实时性强 | 有频率限制,需申请token |
| 新浪财经 | HTTP REST | 免费,接口简单 | 数据格式不稳定,偶尔变更 |
| Wind | Python SDK | 数据最全,机构级 | 收费,年费几万起 |
| Tushare | HTTP REST | 开源免费,社区活跃 | 积分制,高级数据需积分 |
我个人最常用的是Tushare。它提供了A股、港股、基金、期货等各类金融数据,接口设计得很Pythonic。举个例子,获取某只股票的历史行情:
import tushare as ts
# 设置token(在Tushare官网注册获取)
ts.set_token("your_token_here")
pro = ts.pro_api()
# 获取贵州茅台2023年日线数据
df = pro.daily(ts_code="600519.SH", start_date="20230101", end_date="20231231")
print(df.head())
4.2.2 API对接的通用流程
不管对接哪个金融数据源,流程都差不多:
- 注册获取凭证:API Key、Token、App Secret等
- 阅读接口文档:搞清楚请求参数、返回格式、频率限制
- 编写封装函数:把API调用封装成Python函数,方便复用
- 异常处理:网络超时、返回错误码、数据为空等情况都要处理
- 数据缓存:避免重复请求,节省API配额
这里我分享一个自己写的API封装模板:
import requests
import time
from functools import lru_cache
class FinanceAPI:
def __init__(self, token):
self.token = token
self.base_url = "https://api.tushare.pro"
self.last_call_time = 0
@lru_cache(maxsize=128)
def get_stock_data(self, code, start, end):
"""获取股票数据,带缓存和频率控制"""
# 频率控制:每秒最多2次请求
now = time.time()
if now - self.last_call_time < 0.5:
time.sleep(0.5 - (now - self.last_call_time))
payload = {
"api_name": "daily",
"token": self.token,
"params": {"ts_code": code, "start_date": start, "end_date": end},
"fields": "trade_date,open,high,low,close,vol"
}
resp = requests.post(self.base_url, json=payload)
self.last_call_time = time.time()
if resp.status_code == 200:
data = resp.json()
if data["code"] != 0:
raise Exception(f"API错误: {data['msg']}")
return data["data"]["items"]
else:
raise Exception(f"请求失败: {resp.status_code}")
4.3 反爬策略与合规注意事项
这部分很重要,我放在最后说。做金融数据采集,合规是第一位的。我曾经因为爬取某财经网站的新闻数据,被对方法务发了律师函。嗯,从那以后,我对合规格外敏感。
4.3.1 常见的反爬机制
金融网站的反爬手段,说白了就那几招:
- IP封禁:短时间大量请求,直接封IP
- User-Agent检测:非浏览器标识的请求被拒绝
- Cookie验证:需要先访问首页获取Cookie
- 验证码:触发频率限制后弹出验证码
- 动态渲染:数据通过JavaScript加载,直接请求拿不到
怎么应对?我总结了几条实战经验:
- IP代理池:准备一批代理IP,轮换使用。我一般用付费代理,免费的不稳定
- 请求间隔:随机延迟1-3秒,别搞得太规律
- 模拟浏览器:用Selenium或Playwright处理动态渲染的页面
- 分布式爬虫:多台机器、多个IP同时采集,降低单点压力
4.3.2 合规红线
做金融数据采集,有几条红线绝对不能碰:
| 红线 | 说明 | 后果 |
|---|---|---|
| robots.txt | 网站声明禁止爬取的部分 | 可能被起诉侵权 |
| 个人隐私数据 | 用户手机号、身份证、交易记录等 | 违反《个人信息保护法》 |
| 商业机密 | 未公开的财报、内幕信息 | 涉嫌内幕交易 |
| 高频请求 | 对服务器造成过大压力 | 可能构成破坏计算机信息系统罪 |
我个人建议,做金融事件图谱时,只采集公开的、合法的数据。比如上市公司公告、财经新闻、行情数据这些。千万别碰用户隐私和未公开信息。
4.4 本章知识体系
说了这么多,我画了一张图帮你梳理本章的核心逻辑。从数据源到存储,每一步都有对应的技术和注意事项。
这张图把数据采集的流程串起来了。从数据源出发,选择爬虫或API方式,用对应的技术工具实现,同时注意合规和存储。做金融事件图谱,数据采集这一步走稳了,后面的工作才能顺利推进。