Python实战:高效爬取天眼查企业数据的全流程指南
2025.09.18 16:01浏览量:3简介:本文详解如何使用Python爬取天眼查企业数据,涵盖反爬机制破解、数据解析与存储等核心环节,提供可复用的完整代码方案。
一、天眼查数据价值与爬取前提
天眼查作为国内领先的企业信息查询平台,其公开的企业工商信息、司法风险、经营状况等数据对市场分析、竞品调研、投资决策具有重要价值。但直接爬取存在三大挑战:动态加密参数、高频请求拦截、数据结构复杂化。开发者需明确:仅限爬取公开非敏感数据,遵守《网络安全法》与平台服务条款,建议控制单日请求量在200次以内。
二、技术栈选型与工具准备
核心库组合
代理与IP池
使用scrapy-rotating-proxies
中间件,配置付费动态住宅IP(如BrightData),避免被封禁。示例代理配置:
三、反爬机制深度破解
1. 参数加密逆向
天眼查的请求参数包含动态生成的token
与_sign
,通过以下步骤破解:
- 步骤1:使用selenium-wire捕获真实请求
from seleniumwire import webdriver
driver = webdriver.Chrome()
driver.get('https://www.tianyancha.com/search?key=阿里巴巴')
for request in driver.requests:
if request.url.startswith('https://api.tianyancha.com'):
print(request.body) # 获取加密参数样本
- 步骤2:分析参数生成逻辑(通常为JS加密)
通过Chrome开发者工具的Sources面板定位加密JS文件,使用pyexecjs
调用:import execjs
with open('encrypt.js', 'r') as f:
js_code = f.read()
ctx = execjs.compile(js_code)
encrypted_param = ctx.call('generateSign', '原始参数')
2. 行为模拟策略
- 请求头伪装:完善User-Agent、Referer、X-Requested-With等字段
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
'Referer': 'https://www.tianyancha.com/',
'X-Requested-With': 'XMLHttpRequest'
}
- 请求间隔控制:采用指数退避算法
import time
import random
def request_with_delay(url):
delay = 1 + random.uniform(0, 2) * (2 ** retry_count)
time.sleep(delay)
# 执行请求
四、完整爬取流程实现
1. 企业列表页抓取
from requests_html import HTMLSession
session = HTMLSession()
def get_company_list(keyword, page=1):
url = f'https://www.tianyancha.com/search?key={keyword}&pn={page}'
r = session.get(url, headers=headers)
companies = []
for item in r.html.find('.search-result-single'):
name = item.find('.name', first=True).text
link = item.find('.name a', first=True).attrs['href']
companies.append({'name': name, 'link': link})
return companies
2. 企业详情页解析
import parsel
def parse_company_detail(url):
r = session.get(url, headers=headers)
selector = parsel.Selector(r.text)
# 基础信息
base_info = {
'phone': selector.css('.phone::text').get(),
'email': selector.css('.email::text').get(),
'address': selector.css('.address::text').get()
}
# 股东信息(处理嵌套表格)
shareholders = []
for tr in selector.css('.shareholder-table tr')[1:]:
name = tr.css('td:nth-child(1)::text').get()
ratio = tr.css('td:nth-child(2)::text').get()
shareholders.append({'name': name, 'ratio': ratio})
return {'base_info': base_info, 'shareholders': shareholders}
3. 数据存储方案
from pymongo import MongoClient
client = MongoClient('mongodb://localhost:27017/')
db = client['tianyancha_db']
def save_to_mongo(data):
collection = db['companies']
# 处理重复数据
if not collection.find_one({'name': data['name']}):
collection.insert_one(data)
五、进阶优化技巧
分布式爬取
使用Scrapy-Redis实现多节点协作,配置如下:# scrapy_redis.py
REDIS_URL = 'redis://localhost:6379/0'
SCHEDULER = "scrapy_redis.scheduler.Scheduler"
DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter"
增量更新机制
通过企业最后更新时间字段实现增量抓取:def get_updated_companies(last_check_time):
query = {'update_time': {'$gt': last_check_time}}
return list(db.companies.find(query))
异常处理增强
from requests.exceptions import RequestException
import logging
logging.basicConfig(filename='crawler.log', level=logging.ERROR)
def safe_request(url):
try:
return session.get(url, headers=headers, timeout=10)
except RequestException as e:
logging.error(f'Request failed: {e}')
return None
六、法律与伦理规范
合规要点
- 严格遵守robots.txt协议(检查
https://www.tianyancha.com/robots.txt
) - 禁止爬取用户隐私数据(如身份证号、银行账户)
- 商业用途需获得平台授权
- 严格遵守robots.txt协议(检查
数据使用建议
- 对爬取数据进行脱敏处理
- 建立内部数据使用审批流程
- 定期清理过期数据(建议保留不超过1年)
七、完整案例代码
# tianyancha_crawler.py
import time
from requests_html import HTMLSession
from pymongo import MongoClient
import logging
logging.basicConfig(filename='tianyancha.log', level=logging.INFO)
class TianYanChaCrawler:
def __init__(self):
self.session = HTMLSession()
self.headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
'Referer': 'https://www.tianyancha.com/'
}
self.client = MongoClient('mongodb://localhost:27017/')
self.db = self.client['tianyancha_db']
def search_companies(self, keyword, max_pages=5):
all_companies = []
for page in range(1, max_pages + 1):
url = f'https://www.tianyancha.com/search?key={keyword}&pn={page}'
r = self.safe_request(url)
if not r:
continue
companies = []
for item in r.html.find('.search-result-single'):
name = item.find('.name', first=True).text
link = item.find('.name a', first=True).attrs['href']
companies.append({'name': name, 'link': link})
all_companies.extend(companies)
time.sleep(2) # 礼貌性延迟
return all_companies
def parse_detail(self, url):
r = self.safe_request(url)
if not r:
return None
# 解析逻辑(同前文示例)
# ...
return company_data
def safe_request(self, url):
try:
return self.session.get(url, headers=self.headers, timeout=10)
except Exception as e:
logging.error(f'Error fetching {url}: {str(e)}')
return None
if __name__ == '__main__':
crawler = TianYanChaCrawler()
companies = crawler.search_companies('人工智能', max_pages=3)
for company in companies:
detail = crawler.parse_detail(company['link'])
if detail:
crawler.db.companies.insert_one(detail)
八、常见问题解决方案
验证码触发
- 现象:返回403且HTML包含验证码图片
- 解决方案:接入第三方打码平台(如超级鹰),或降低请求频率
数据缺失
- 检查是否登录后才能查看的数据(需模拟登录)
- 确认CSS选择器是否随页面更新而改变
内存溢出
- 对大规模数据采用流式处理
- 使用生成器代替列表存储:
def generate_companies(keyword):
for page in range(1, 100):
# 抓取逻辑
yield company_data
通过本文提供的完整方案,开发者可在遵守法律法规的前提下,高效构建天眼查数据爬取系统。实际部署时建议结合具体业务需求调整爬取频率与数据范围,并定期监控爬虫运行状态。
发表评论
登录后可评论,请前往 登录 或 注册