第二章:ESG数据采集——数据源分类与实战获取
各位同学,欢迎来到第二章。上一章我们聊了ESG评级模型的整体框架,今天咱们来点实在的——数据从哪来?怎么拿?
说实话,ESG分析最头疼的不是模型有多复杂,而是数据本身。我做了这么多年ESG项目,见过太多团队模型建得漂漂亮亮,最后死在数据质量上。嗯,咱们今天就把这个坎儿迈过去。
2.1 数据源分类:三大来源
ESG数据不像股票价格那样有统一的交易所报价。它散落在各个角落。我个人习惯把它们分成三大类:
2.1.1 企业自主披露
这是最直接的数据源。企业发布ESG报告、可持续发展报告、年报中的ESG章节,都属于这一类。
- 优点:结构化程度高,数据相对规范
- 缺点:自说自话,有漂绿风险
- 典型来源:公司官网、交易所披露平台(如港交所ESG披露平台)
2.1.2 政府与监管数据
政府公开数据是ESG分析的金矿。环境处罚、排污许可证、社保缴纳记录……这些数据造假成本极高,可信度强。
- 优点:权威性高,法律约束力强
- 缺点:更新频率低,覆盖范围有限
- 典型来源:生态环境部、证监会、国家统计局
2.1.3 新闻舆情与另类数据
这部分是我个人觉得最有意思的。社交媒体、新闻、NGO报告、卫星图像……这些非结构化数据能捕捉到企业披露里看不到的东西。
- 优点:实时性强,能发现突发事件
- 缺点:噪音大,需要NLP处理
- 典型来源:新闻API、Twitter、Reddit、全球环境新闻数据库
核心观点:好的ESG数据策略,一定是三类数据源的组合。单一来源风险太大。
2.2 API数据获取实战
讲完了分类,咱们上手实操。API是获取结构化数据最优雅的方式。我以两个主流数据商为例:
2.2.1 MSCI ESG API 示例
MSCI的ESG评级是行业标杆。他们的API需要申请密钥,但流程不复杂。
import requests
import json
# 配置你的API密钥
API_KEY = "your_msci_api_key_here"
BASE_URL = "https://api.msci.com/esg/v1"
headers = {
"Authorization": f"Bearer {API_KEY}",
"Content-Type": "application/json"
}
# 查询某公司的ESG评级
def get_esg_rating(company_isin):
endpoint = f"{BASE_URL}/ratings/{company_isin}"
response = requests.get(endpoint, headers=headers)
if response.status_code == 200:
data = response.json()
return {
"company": data["companyName"],
"rating": data["esgRating"],
"score": data["esgScore"],
"date": data["ratingDate"]
}
else:
print(f"请求失败:{response.status_code}")
return None
# 示例:查询苹果公司(ISIN: US0378331005)
result = get_esg_rating("US0378331005")
print(result)
2.2.2 Refinitiv(路孚特)API 示例
Refinitiv的数据覆盖面更广,特别是碳排放数据比较全。
from refinitiv.data import content
import refinitiv.data as rd
# 初始化会话
rd.open_session()
# 获取ESG数据
def get_refinitiv_esg(ric_code):
"""
RIC代码示例:AAPL.O(苹果)
"""
fields = [
"TR.ESGScore",
"TR.EnvironmentalScore",
"TR.SocialScore",
"TR.GovernanceScore",
"TR.TotalCO2Emission"
]
data = content.get_data(
universe=[ric_code],
fields=fields
)
return data
# 获取苹果公司数据
apple_esg = get_refinitiv_esg("AAPL.O")
print(apple_esg)
rd.close_session()
为什么会用两个不同的API?说白了,不同数据商对同一家公司的评级可能不一样。我习惯拿MSCI和Refinitiv的数据做交叉验证,取个平均值或者加权值。
2.3 网络爬虫基础与合规性
API虽好,但有些数据没有公开API怎么办?这时候就需要爬虫了。但注意——爬虫不是你想爬,想爬就能爬。
2.3.1 基础爬虫示例
以爬取企业ESG报告PDF链接为例:
import requests
from bs4 import BeautifulSoup
import re
def crawl_esg_reports(company_url):
"""
爬取公司官网上的ESG报告链接
"""
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"
}
try:
response = requests.get(company_url, headers=headers, timeout=10)
soup = BeautifulSoup(response.text, 'html.parser')
# 查找包含"ESG"或"sustainability"的PDF链接
pdf_links = []
for link in soup.find_all('a', href=True):
href = link['href']
text = link.get_text().lower()
if href.endswith('.pdf') and ('esg' in text or 'sustain' in text):
pdf_links.append({
'title': link.get_text().strip(),
'url': href if href.startswith('http') else company_url + href
})
return pdf_links
except Exception as e:
print(f"爬取失败:{e}")
return []
# 示例
links = crawl_esg_reports("https://www.apple.com/environment/")
for link in links[:5]:
print(f"{link['title']}: {link['url']}")
2.3.2 合规性——避坑指南
我曾经因为爬虫吃过亏。2019年爬某个政府网站的数据,没注意robots.txt,结果被对方发了律师函。从那以后,我给自己定了三条铁律:
- 先看robots.txt:网站根目录下的robots.txt明确告诉你哪些能爬哪些不能爬
- 控制频率:加延时,别把人家服务器搞崩了。我一般设置2-5秒的间隔
- 尊重版权:爬下来的数据如果用于商业用途,一定要确认授权
合规检查清单:
- ✅ 检查网站服务条款(ToS)
- ✅ 检查robots.txt
- ✅ 设置合理的User-Agent
- ✅ 添加请求延时
- ✅ 不爬取个人隐私数据
- ✅ 不绕过登录验证
2.4 本章知识体系总览
下面这张图是我自己画的,把数据采集的整个流程串起来了。你想想看,从数据源到最终入库,中间要经过多少道工序?
2.5 数据采集的常见坑
最后,分享几个我踩过的坑:
| 坑 | 表现 | 解决方案 |
|---|---|---|
| API密钥过期 | 突然拿不到数据 | 写个定时任务,提前7天提醒续费 |
| 网站改版 | 爬虫抓不到内容 | 加监控,发现异常立刻告警 |
| 数据格式不一致 | 同一家公司不同来源数据对不上 | 建立统一的数据字典,做映射 |
| 法律风险 | 被数据源方起诉 | 采集前务必确认合规性 |
我的建议:刚开始做ESG数据采集,别贪多。先盯住3-5家核心公司,把数据链路跑通,再慢慢扩展。我见过太多人一上来就想覆盖全市场,结果数据质量一塌糊涂。
好了,这一章的内容就到这里。数据采集是ESG分析的基石,地基打不牢,后面模型再漂亮也是空中楼阁。下一章咱们聊聊数据清洗和预处理——那才是真正考验耐心的地方。