
简介这是一套基于Python 3.6开发的企业信息采集实战项目专为计算机类本科毕业设计、课程设计及初阶Web数据采集项目开发打造。资源聚焦企查查平台企业分类信息的自动化获取涵盖从目标企业列表读取、请求构造、反爬应对含cookies/headers/代理机制、HTML解析到结构化数据入库支持MySQL的完整链路适合具备基础Python和HTTP知识的学习者进阶实践。压缩包共54个文件以33个核心Python脚本为主如start.py主流程、parse模块下多级解析逻辑、use_mysql.py数据库交互辅以5个XML配置文件、2个HTML示例页及README等辅助文档整体仅119KB轻量易读、结构清晰。目前已有159人学习下载源码经严格测试包含可直接运行的采集流程、模块化设计com_common/com_basic/com_expand分层处理、实用工具类proxy.py/others.py及调试用test文件便于理解数据流转逻辑并快速二次开发。1. 用 Python 抓取企查查企业分类页不是“爬虫入门练习”而是毕业设计里最常卡壳的真实场景很多计算机专业学生在做毕业设计或课程设计时选题写着“基于 Python 的企业信息采集系统”结果一打开企查查网站就懵了页面全是 JavaScript 渲染搜索框没 form 表单翻页没传统 URL 参数点开一家公司详情页URL 里连企业名都看不到。更麻烦的是刚写好 requests BeautifulSoup 脚本跑两轮就返回 403 或空白 div——不是代码错了是请求头、时间间隔、加密参数全没对上。这不是“学不会爬虫”而是没踩过企查查这类反爬成熟站点的典型坑。本文聚焦「企业分类信息」这一可公开访问的入口如“制造业”“软件和信息技术服务业”等一级/二级行业分类页不碰登录态、不绕风控黑盒用合法、稳定、可复现的方式批量获取分类下企业列表的名称、统一社会信用代码、注册地址、成立日期等结构化字段。适合正在写毕设开题报告、需要交付源码文档可运行 demo 的同学也适合想快速验证某行业企业分布的技术人员。2. 为什么不用 Selenium从请求链路拆解企查查分类页的真实加载逻辑2.1 分类页数据并非前端渲染而是由 XHR 接口动态注入打开企查查任意行业分类页例如 https://www.qcc.com/firm/industry-100000000.html按 F12 打开开发者工具切换到 Network → XHR 标签刷新页面。你会看到一个名为search的请求URL 类似https://www.qcc.com/api/search/searchList?...其响应体是标准 JSON包含total总条数、list企业列表数组等字段。这说明页面主体内容由 AJAX 加载非服务端直出 HTMLlist数组中每个对象已含企业名称、法人、注册资本、成立日期、地址等关键字段分类 ID如industry-100000000中的100000000实际映射为接口参数industry分页靠page和pageSize控制非 URL path 变化。提示不要用 Selenium 模拟点击“下一页”按钮。它启动慢、内存占用高、易被识别为自动化行为。直接调用searchList接口效率提升 5 倍以上且规避了浏览器指纹检测。2.2 关键请求头必须还原缺一不可对比浏览器真实请求与 Python 默认 requests 请求以下 4 个 Header 是企查查服务端校验的核心Header 字段浏览器真实值示例作用说明User-AgentMozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36基础设备标识需匹配主流版本Cookieqcc_tokenxxx; acw_tcxxx; ...包含会话凭证其中qcc_token有效期约 2 小时需登录后手动提取X-Requested-WithXMLHttpRequest告知服务端这是 AJAX 请求影响响应格式Refererhttps://www.qcc.com/firm/industry-100000000.html防盗链校验必须与目标分类页 URL 一致# 正确构造 headers以制造业分类为例 headers { User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36, Cookie: qcc_tokeneyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.xxx; acw_tc76b20f8a1715xxxxx; QCCSESSIDabc123def456;, X-Requested-With: XMLHttpRequest, Referer: https://www.qcc.com/firm/industry-100000000.html }注意qcc_token必须从已登录的浏览器中复制。打开企查查 → 登录账号 → 访问任意分类页 → F12 → Application → Cookies → 找到qcc_token值。该 token 与登录设备强绑定换电脑或清缓存后失效不能共享、不能硬编码进源码。毕设演示时需在 README.md 中明确写出“请自行登录获取 token”。2.3 请求参数解析industry、page、pageSize是核心三元组searchList接口完整 URL 示例https://www.qcc.com/api/search/searchList?industry100000000page1pageSize20isCommonSearchtruesortFieldregCapitalsortTypedescindustry: 分类 ID对应企查查行业树节点。常见值100000000制造业、110000000信息传输、软件和信息技术服务业、120000000金融业。可在页面 URL 或网页源码中提取搜索industryIdpage: 当前页码从 1 开始pageSize: 每页条数最大支持 20设更大值会被截断sortFieldsortType: 排序字段regCapital注册资本estiblishTime成立日期及方向asc/desc非必需但影响数据覆盖度。# 构造请求 URL 的函数 def build_search_url(industry_id: str, page: int 1, page_size: int 20) - str: base_url https://www.qcc.com/api/search/searchList params { industry: industry_id, page: str(page), pageSize: str(page_size), isCommonSearch: true, sortField: estiblishTime, # 按成立日期排序避免漏掉新注册企业 sortType: desc } return base_url ? .join([f{k}{v} for k, v in params.items()]) # 示例获取制造业第 1 页 url build_search_url(industry_id100000000, page1) print(url) # https://www.qcc.com/api/search/searchList?industry100000000page1pageSize20...3. 用 requests json 解析实现企业分类信息采集附完整可运行脚本3.1 安装依赖与环境准备本方案仅依赖requests和pandas无 Selenium、无浏览器驱动轻量可靠。推荐使用 Python 3.8虚拟环境隔离依赖# 创建并激活虚拟环境 python -m venv qcc_env source qcc_env/bin/activate # Linux/macOS # qcc_env\Scripts\activate # Windows # 安装必要库 pip install requests pandas openpyxl提示不要用urllib或http.client替代requests。前者需手动拼接 URL、处理编码、管理 Cookie极易出错requests的Session对象能自动维护 Cookie简化重试逻辑。3.2 核心采集函数带重试、异常捕获、JSON 解析以下函数完成单页请求、状态码校验、JSON 解析、字段提取四步操作。关键点使用requests.Session()复用连接提升多页请求速度设置timeout(10, 20)连接 10 秒读取 20 秒避免卡死对429 Too Many Requests做指数退避重试最多 3 次从response.json()[data][list]提取企业列表字段名与 API 响应严格一致。import requests import time import random import json from typing import List, Dict, Optional def fetch_page_data( session: requests.Session, headers: Dict[str, str], industry_id: str, page: int, page_size: int 20 ) - Optional[List[Dict]]: 获取单页企业数据 :param session: requests.Session 实例 :param headers: 已配置的请求头 :param industry_id: 行业分类 ID :param page: 页码从 1 开始 :param page_size: 每页条数默认 20 :return: 企业字典列表失败返回 None url fhttps://www.qcc.com/api/search/searchList?industry{industry_id}page{page}pageSize{page_size}isCommonSearchtruesortFieldestiblishTimesortTypedesc for attempt in range(3): # 最多重试 3 次 try: response session.get(url, headersheaders, timeout(10, 20)) if response.status_code 200: data response.json() if data in data and list in data[data]: return data[data][list] else: print(f[警告] 第 {page} 页响应无 data.list 字段响应: {data}) return None elif response.status_code 429: wait_time (2 ** attempt) random.uniform(0, 1) print(f[等待] 触发限流{wait_time:.2f}秒后重试第 {attempt1} 次...) time.sleep(wait_time) continue else: print(f[错误] 第 {page} 页请求失败状态码: {response.status_code}) return None except requests.exceptions.Timeout: print(f[超时] 第 {page} 页请求超时第 {attempt1} 次重试...) continue except requests.exceptions.RequestException as e: print(f[异常] 第 {page} 页请求异常: {e}) continue except json.JSONDecodeError: print(f[解析错误] 第 {page} 页响应非 JSON 格式) return None return None3.3 批量采集与数据清洗从 JSON 到 Excel 表格企查查 API 返回的字段名与中文业务含义不完全对应需映射清洗。例如name→ 企业名称legalPersonName→ 法定代表人regCapital→ 注册资本字符串含“万元”“亿美元”等单位estiblishTime→ 成立日期ISO 格式2015-03-12regLocation→ 注册地址以下函数将原始 JSON 列表转换为 Pandas DataFrame并标准化字段import pandas as pd def clean_company_data(raw_list: List[Dict]) - pd.DataFrame: 清洗企业原始数据提取关键字段并标准化 cleaned [] for item in raw_list: # 提取基础字段缺失则填空字符串 company { 企业名称: item.get(name, ), 法定代表人: item.get(legalPersonName, ), 注册资本: item.get(regCapital, ), 成立日期: item.get(estiblishTime, ), 注册地址: item.get(regLocation, ), 统一社会信用代码: item.get(creditCode, ), 经营范围: item.get(scope, )[:200] ... if len(item.get(scope, )) 200 else item.get(scope, ) } cleaned.append(company) return pd.DataFrame(cleaned) # 主采集流程示例 if __name__ __main__: # 1. 配置 headers务必替换为你的 qcc_token headers { User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36, Cookie: qcc_tokenYOUR_TOKEN_HERE; acw_tcxxx; QCCSESSIDxxx;, X-Requested-With: XMLHttpRequest, Referer: https://www.qcc.com/firm/industry-100000000.html } session requests.Session() all_companies [] # 2. 采集制造业industry100000000前 5 页共 100 条 for page in range(1, 6): print(f正在获取第 {page} 页...) raw_data fetch_page_data(session, headers, 100000000, page) if raw_data: all_companies.extend(raw_data) time.sleep(1 random.uniform(0, 0.5)) # 每页间随机延时 1~1.5 秒 # 3. 清洗并保存为 Excel if all_companies: df clean_company_data(all_companies) output_file 企查查_制造业企业名录_2024.xlsx df.to_excel(output_file, indexFalse) print(f✅ 采集完成共 {len(df)} 条数据已保存至 {output_file}) else: print(❌ 未获取到任何数据请检查 headers 或网络连接)4. 毕设落地关键如何把采集脚本包装成“可演示、可答辩、可扩展”的项目4.1 项目结构设计让导师一眼看懂技术分层毕业设计不是扔一个.py文件而是体现工程思维。推荐目录结构如下根目录qcc-collectorqcc-collector/ ├── main.py # 入口脚本调用采集逻辑 ├── collector/ # 核心模块 │ ├── __init__.py │ ├── api_client.py # 封装 fetch_page_data 等函数 │ └── data_cleaner.py # clean_company_data 等清洗逻辑 ├── config/ # 配置分离 │ └── settings.py # 存放 industry_map、headers 模板、默认参数 ├── data/ # 输出目录git ignore │ └── output.xlsx ├── requirements.txt # pip freeze requirements.txt └── README.md # 含项目简介、运行步骤、headers 获取指南、字段说明提示settings.py中定义INDUSTRY_MAP {制造业: 100000000, 软件业: 110000000}避免硬编码 IDREADME.md用截图展示“如何从浏览器复制 qcc_token”比文字描述更直观。4.2 增加命令行参数支持提升答辩演示灵活性导师可能现场提问“能换个行业试试吗”“能导出 CSV 吗”。用argparse支持动态参数无需改代码# main.py 片段 import argparse from collector.api_client import fetch_all_pages from collector.data_cleaner import clean_company_data if __name__ __main__: parser argparse.ArgumentParser(description企查查企业分类信息采集工具) parser.add_argument(--industry, -i, requiredTrue, help行业分类ID如 100000000) parser.add_argument(--pages, -p, typeint, default5, help采集页数默认5页) parser.add_argument(--output, -o, defaultoutput.xlsx, help输出文件名默认output.xlsx) parser.add_argument(--format, choices[xlsx, csv], defaultxlsx, help输出格式) args parser.parse_args() # 从 config/settings.py 加载 headers 模板再提示用户填入 token from config.settings import get_headers_template headers get_headers_template() headers[Cookie] input(请输入你的 qcc_token格式qcc_tokenxxx; ...: ) # 执行采集 raw_data fetch_all_pages(headers, args.industry, args.pages) df clean_company_data(raw_data) if args.format xlsx: df.to_excel(args.output, indexFalse) else: df.to_csv(args.output, indexFalse, encodingutf-8-sig) print(f✅ 已导出 {len(df)} 条数据至 {args.output})运行方式python main.py -i 110000000 -p 3 -o 软件业企业.xlsx --format xlsx4.3 毕设答辩必答问题预演3 个高频技术点与应答逻辑问题应答要点简洁、准确、体现思考Q企查查有反爬你们怎么保证稳定采集“我们不模拟浏览器而是分析其真实 XHR 接口。关键在于还原qcc_token登录态凭证、Referer防盗链、X-Requested-WithAJAX 标识三个 Header。Token 需用户手动提供符合合规要求每页间加入随机延时避免触发频率限制。”Q数据字段不全比如没有联系电话怎么办“当前采集的是分类页公开列表数据字段由企查查 API 直接返回我们不做二次请求。若需深度字段电话、邮箱需进入详情页但详情页有更强反爬。毕设范围聚焦‘分类维度宏观统计’已满足题目‘企业分类信息采集’要求。”Q代码里写死了 industry ID怎么扩展新行业“我们在config/settings.py中维护INDUSTRY_MAP字典新增行业只需添加键值对。main.py支持--industry参数传入 ID也可通过--industry-name查表转换扩展性已预留。”5. 进阶技巧用 pandas 分析采集结果生成毕设加分项图表5.1 按成立年份统计企业数量画趋势折线图采集到的成立日期字段是字符串如2020-05-12用 pandas 提取年份并聚合import matplotlib.pyplot as plt # 假设 df 是 clean_company_data() 返回的 DataFrame df[成立年份] pd.to_datetime(df[成立日期]).dt.year # 统计各年份企业数 year_count df[成立年份].value_counts().sort_index() # 绘图 plt.figure(figsize(10, 6)) plt.plot(year_count.index, year_count.values, markero, linewidth2, markersize6) plt.title(制造业企业历年成立数量趋势, fontsize14) plt.xlabel(成立年份, fontsize12) plt.ylabel(企业数量, fontsize12) plt.grid(True, alpha0.3) plt.xticks(year_count.index, rotation0) plt.tight_layout() plt.savefig(manufacturing_year_trend.png, dpi300, bbox_inchestight) plt.show()5.2 提取注册资本数值做区间分布直方图注册资本字段含单位“1000万元”“50万美元”需清洗为纯数字万元为单位import re def parse_reg_capital(text: str) - float: 解析注册资本字符串为万元数值 if not text: return 0.0 # 匹配数字 单位 match re.search(r([\d\.])\s*(?:万|亿)?元, text) if match: num float(match.group(1)) # 处理“亿元”情况 if 亿元 in text: return num * 10000 else: return num return 0.0 df[注册资本_万元] df[注册资本].apply(parse_reg_capital) df[注册资本_万元].hist(bins30, edgecolorblack, alpha0.7) plt.title(制造业企业注册资本分布万元, fontsize14) plt.xlabel(注册资本万元, fontsize12) plt.ylabel(企业数量, fontsize12) plt.grid(True, alpha0.3) plt.savefig(manufacturing_capital_dist.png, dpi300, bbox_inchestight)5.3 导出字段说明表嵌入毕设论文附录将clean_company_data()中的字段映射整理为 Markdown 表格直接复制进论文字段名数据来源说明示例企业名称name企业在企查查登记的全称“华为技术有限公司”法定代表人legalPersonName工商登记的法人姓名“赵明”注册资本regCapital登记注册资本含单位“1000万元”成立日期estiblishTimeISO 格式日期字符串“2015-03-12”注册地址regLocation工商登记注册地址“广东省深圳市龙岗区坂田华为总部办公楼”统一社会信用代码creditCode国家企业信用信息公示系统唯一编码“9144030019220500XX”经营范围scope工商登记的营业范围截取前200字符“从事集成电路…略”提示此表体现你对数据源的理解深度比单纯贴代码更有说服力。在论文“数据采集与预处理”章节插入标注“数据字段说明来源企查查 API 响应”。本文还有配套的精品资源点击获取