如何用Python高效查询天眼查企业信息:技术实现与实战指南
2025.09.18 16:01浏览量:1简介:本文详解如何通过Python自动化查询天眼查企业信息,涵盖API调用、网页解析、反爬策略及数据存储方案,提供可复用的代码示例与最佳实践。
一、技术选型与前期准备
1.1 查询方式对比
天眼查企业信息查询主要有三种技术路径:
- 官方API接口:需申请企业级账号,支持结构化数据返回(推荐指数★★★★☆)
- 网页爬取:通过解析HTML获取数据,需处理动态加载与反爬机制(推荐指数★★★☆☆)
- 浏览器自动化:使用Selenium模拟人工操作,适合复杂交互场景(推荐指数★★☆☆☆)
关键决策点:
- 官方API提供最高稳定性,但需承担商业授权费用
- 爬虫方案零成本但需持续维护,适合个人开发者或小规模应用
- 浏览器自动化仅作为备选方案,性能效率较低
1.2 环境配置清单
二、官方API实现方案
2.1 认证流程详解
- 账号注册:访问天眼查开发者平台完成企业认证
- API密钥获取:在控制台创建应用获取
appKey
和appSecret
- 权限配置:申请企业信息查询权限(需提供使用场景说明)
2.2 核心代码实现
import requests
import hashlib
import time
class TianYanChaAPI:
def __init__(self, app_key, app_secret):
self.app_key = app_key
self.app_secret = app_secret
self.base_url = "https://open.tianyancha.com/services/v3/open/"
def generate_sign(self, params):
"""生成请求签名"""
sorted_params = sorted(params.items(), key=lambda x: x[0])
param_str = "&".join([f"{k}={v}" for k, v in sorted_params])
sign_str = f"{param_str}{self.app_secret}"
return hashlib.md5(sign_str.encode()).hexdigest()
def query_company(self, company_name):
"""企业基本信息查询"""
timestamp = str(int(time.time()))
params = {
"appKey": self.app_key,
"timestamp": timestamp,
"name": company_name,
"pageSize": 10
}
params["sign"] = self.generate_sign(params)
try:
response = requests.get(
f"{self.base_url}company/searchBaseInfoList",
params=params
)
response.raise_for_status()
return response.json()
except requests.exceptions.RequestException as e:
print(f"API请求失败: {e}")
return None
# 使用示例
api_client = TianYanChaAPI("your_app_key", "your_app_secret")
result = api_client.query_company("阿里巴巴")
print(result)
2.3 返回数据解析
典型响应结构包含:
{
"code": 200,
"message": "success",
"result": {
"total": 1,
"items": [
{
"id": 123456,
"name": "阿里巴巴集团",
"legalPersonName": "张勇",
"registeredCapital": "100000万人民币",
"establishTime": "1999-09-09"
}
]
}
}
三、网页爬取实现方案
3.1 反爬机制分析
天眼查主要反爬策略:
- IP频率限制:单IP每分钟请求不超过5次
- 行为检测:监测鼠标轨迹、点击间隔等特征
- 参数加密:关键查询参数采用JS动态生成
3.2 绕过策略实现
from fake_useragent import UserAgent
import random
class TianYanChaSpider:
def __init__(self):
self.ua = UserAgent()
self.session = requests.Session()
self.proxies = [
"http://proxy1.example.com:8080",
"http://proxy2.example.com:8080"
]
def get_random_proxy(self):
"""随机轮换代理IP"""
return {"http": random.choice(self.proxies)}
def get_company_info(self, company_name):
"""获取企业详情页信息"""
headers = {
"User-Agent": self.ua.random,
"Referer": "https://www.tianyancha.com/"
}
# 第一步:获取搜索结果页
search_url = f"https://www.tianyancha.com/search?key={company_name}"
try:
response = self.session.get(
search_url,
headers=headers,
proxies=self.get_random_proxy(),
timeout=10
)
# 解析企业ID(示例简化)
company_id = self._parse_company_id(response.text)
# 第二步:访问企业详情页
detail_url = f"https://www.tianyancha.com/company/{company_id}"
detail_resp = self.session.get(
detail_url,
headers=headers,
proxies=self.get_random_proxy()
)
return self._parse_detail_page(detail_resp.text)
except Exception as e:
print(f"请求失败: {e}")
return None
def _parse_company_id(self, html):
"""从搜索结果解析企业ID(需根据实际HTML结构调整)"""
# 实际实现需使用BeautifulSoup或正则表达式
pass
3.3 动态参数处理
对于加密参数_token
的获取方案:
- 使用Selenium加载页面获取完整DOM
- 执行JS代码提取加密参数:
```python
from selenium import webdriver
def get_dynamic_token(company_name):
driver = webdriver.Chrome()
driver.get(“https://www.tianyancha.com/search“)
# 输入搜索词并触发查询
search_box = driver.find_element("name", "key")
search_box.send_keys(company_name)
search_box.submit()
# 等待结果加载后提取token
token = driver.execute_script("""
return window._token || document.querySelector('input[name="_token"]').value;
""")
driver.quit()
return token
# 四、数据存储与处理
## 4.1 结构化存储方案
推荐MongoDB存储方案:
```python
from pymongo import MongoClient
class DataStorage:
def __init__(self):
self.client = MongoClient("mongodb://localhost:27017/")
self.db = self.client["tianyancha"]
self.companies = self.db["companies"]
def save_company(self, company_data):
"""存储企业信息"""
filter_cond = {"id": company_data["id"]}
update_op = {
"$set": {
"name": company_data["name"],
"legal_person": company_data["legalPersonName"],
"update_time": datetime.now()
}
}
self.companies.update_one(filter_cond, update_op, upsert=True)
4.2 数据清洗建议
- 字段标准化:
- 注册资本统一转换为数值(处理”万人民币”、”美元”等单位)
- 日期字段统一为YYYY-MM-DD格式
- 异常值处理:
- 过滤无效的法人名称(如”—“、”未知”等)
- 校验联系电话格式
五、最佳实践与注意事项
5.1 法律合规要点
5.2 性能优化建议
- 异步处理:使用aiohttp实现并发请求
- 缓存机制:对重复查询结果进行本地缓存
- 分布式架构:使用Scrapy-Redis实现分布式爬取
5.3 错误处理策略
def robust_query(company_name, max_retries=3):
"""带重试机制的查询函数"""
for attempt in range(max_retries):
try:
# 实际查询逻辑
result = api_client.query_company(company_name)
if result and result.get("code") == 200:
return result
except Exception as e:
wait_time = 2 ** attempt # 指数退避
time.sleep(wait_time)
raise RuntimeError("查询失败")
六、进阶应用场景
6.1 批量查询实现
def batch_query(company_list):
"""批量查询企业信息"""
results = []
with ThreadPoolExecutor(max_workers=5) as executor:
futures = [
executor.submit(api_client.query_company, name)
for name in company_list
]
for future in as_completed(futures):
results.append(future.result())
return results
6.2 变更监控系统
- 定时任务:使用Celery设置每日凌晨执行
- 差异检测:对比当日与历史数据的关键字段
- 告警机制:通过邮件/短信通知变更
6.3 数据可视化应用
推荐使用Pyecharts生成企业关系图谱:
from pyecharts import options as opts
from pyecharts.charts import Graph
def generate_relation_graph(company_data):
nodes = [
{"name": "阿里巴巴", "symbolSize": 50},
{"name": "蚂蚁集团", "symbolSize": 40}
]
links = [{"source": "阿里巴巴", "target": "蚂蚁集团"}]
graph = (
Graph()
.add("", nodes, links, repulsion=1000)
.set_global_opts(title_opts=opts.TitleOpts(title="企业关系图谱"))
)
return graph.render("relation_graph.html")
七、总结与展望
本方案提供了从基础查询到高级应用的完整实现路径,开发者可根据实际需求选择API或爬虫方案。未来可拓展方向包括:
- 结合NLP技术实现企业风险预警
- 构建企业知识图谱支持智能查询
- 开发微信小程序实现移动端查询
建议开发者持续关注天眼查的反爬策略更新,保持代码库的维护频率。对于生产环境应用,推荐优先采用官方API方案以确保服务稳定性。
发表评论
登录后可评论,请前往 登录 或 注册