Python实战:高效爬取天眼查企业数据的全流程指南
2025.09.18 16:01浏览量:92简介:本文详解如何使用Python爬取天眼查企业数据,涵盖反爬机制破解、数据解析与存储等核心环节,提供可复用的完整代码方案。
一、天眼查数据价值与爬取前提
天眼查作为国内领先的企业信息查询平台,其公开的企业工商信息、司法风险、经营状况等数据对市场分析、竞品调研、投资决策具有重要价值。但直接爬取存在三大挑战:动态加密参数、高频请求拦截、数据结构复杂化。开发者需明确:仅限爬取公开非敏感数据,遵守《网络安全法》与平台服务条款,建议控制单日请求量在200次以内。
二、技术栈选型与工具准备
核心库组合
代理与IP池
使用scrapy-rotating-proxies中间件,配置付费动态住宅IP(如BrightData),避免被封禁。示例代理配置:
三、反爬机制深度破解
1. 参数加密逆向
天眼查的请求参数包含动态生成的token与_sign,通过以下步骤破解:
- 步骤1:使用selenium-wire捕获真实请求
from seleniumwire import webdriverdriver = 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 execjswith 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 timeimport randomdef request_with_delay(url):delay = 1 + random.uniform(0, 2) * (2 ** retry_count)time.sleep(delay)# 执行请求
四、完整爬取流程实现
1. 企业列表页抓取
from requests_html import HTMLSessionsession = 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).textlink = item.find('.name a', first=True).attrs['href']companies.append({'name': name, 'link': link})return companies
2. 企业详情页解析
import parseldef 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 MongoClientclient = 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.pyREDIS_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 RequestExceptionimport logginglogging.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.pyimport timefrom requests_html import HTMLSessionfrom pymongo import MongoClientimport logginglogging.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:continuecompanies = []for item in r.html.find('.search-result-single'):name = item.find('.name', first=True).textlink = item.find('.name a', first=True).attrs['href']companies.append({'name': name, 'link': link})all_companies.extend(companies)time.sleep(2) # 礼貌性延迟return all_companiesdef parse_detail(self, url):r = self.safe_request(url)if not r:return None# 解析逻辑(同前文示例)# ...return company_datadef 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 Noneif __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
通过本文提供的完整方案,开发者可在遵守法律法规的前提下,高效构建天眼查数据爬取系统。实际部署时建议结合具体业务需求调整爬取频率与数据范围,并定期监控爬虫运行状态。

发表评论
登录后可评论,请前往 登录 或 注册