![](https://ucc.alicdn.com/2qom7lwjnrsms/developer-article1652032/20250213/270c0ce598d24bd7b6f73830f6f5f313.jpeg?x-oss-process=image/resize,w_1400/format,webp)
时间轴呈现事故进程
- 17:00:开发人员小李正在尝试利用 Python 爬虫从企查查(https://www.qcc.com)抓取公司工商信息。原本一切正常,但突然发现信息采集失败,程序抛出大量选择器错误。
- 17:15:小李发现,尽管请求能正常返回 HTML 页面,但关键数据(公司名称、法人代表、注册资本)的定位选择器失效,抓取到的内容为空或错误。初步判断是网页结构发生了不可预料的变化。
- 17:30:尝试更新选择器,但新问题接踵而至:动态加载的内容无法被解析,数据仍然缺失。
分析式线索追踪
本地测试日志片段
# 爬虫日志输出
[17:15:23] INFO - 发送 GET 请求至 https://www.qcc.com,状态码 200,请求成功。
[17:15:25] ERROR - 选择器失效!无法找到公司名称元素 (selector: #companyName)。
[17:15:30] DEBUG - HTML 快照保存至 ./snapshots/qcc_17_15_25.html,便于后续分析。
网页结构与选择器对比
- 原始选择器:
<font style="color:rgb(38, 38, 38);">#companyName</font>
用于定位公司名称。
- 快照 HTML 分析:发现
<font style="color:rgb(38, 38, 38);"><div id="companyName"></font>
标签已不存在,取而代之的是动态加载的 <font style="color:rgb(38, 38, 38);"><div class="loader"></font>
和 <font style="color:rgb(38, 38, 38);"><script></font>
标签。
解决方案探寻过程
- 重新审视网页加载过程:
- 使用浏览器开发者工具(F12)查看网页加载流程,发现关键信息是通过 JavaScript 动态渲染的,原先的静态 HTML 并不含有所需数据。
- 临时策略:引入 Selenium 模拟浏览器行为,确保 JavaScript 执行,完整加载页面。
- 代理 IP 与反爬机制突破:
proxies = {
'http': 'http://用户名:密码@域名:端口',
'https': 'https://用户名:密码@域名:端口',
}
response = requests.get(url, proxies=proxies)
- <font style="color:rgb(38, 38, 38);">企查查对频繁请求有严格限制,需借助代理 IP。参考亿牛云爬虫代理参数(域名、端口、用户名、密码),设置代码:</font>
- Cookie 和 User-Agent 设置:
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36',
'Cookie': 'your-cookie-string'
}
- <font style="color:rgb(38, 38, 38);">仿制正常浏览器行为,避免被服务器识别为爬虫:</font>
- 调试选择器工具选择:
- 使用 BeautifulSoup 或 lxml 库解析渲染后的 HTML,结合 XPath 和 CSS 选择器重新定位元素。
改进后的代码实现
import requests
from bs4 import BeautifulSoup
PROXY_USERNAME = '16YUN'
PROXY_PASSWORD = '16IP'
PROXY_DOMAIN = 'proxy.16yun.cn'
PROXY_PORT = '8080'
proxies = {
'http': f'http://{PROXY_USERNAME}:{PROXY_PASSWORD}@{PROXY_DOMAIN}:{PROXY_PORT}',
'https': f'https://{PROXY_USERNAME}:{PROXY_PASSWORD}@{PROXY_DOMAIN}:{PROXY_PORT}',
}
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36',
'Cookie': 'your-cookie-string'
}
url = "https://www.qcc.com"
response = requests.get(url, headers=headers, proxies=proxies)
response.encoding = 'utf-8'
soup = BeautifulSoup(response.text, 'html.parser')
company_name = soup.select_one('.company-name')
if company_name:
print(f"公司名称: {company_name.text.strip()}")
else:
print("未能获取公司名称!")
legal_representative = soup.select_one('.legal-rep')
if legal_representative:
print(f"法人代表: {legal_representative.text.strip()}")
else:
print("未能获取法人代表信息!")
registered_capital = soup.select_one('.reg-capital')
if registered_capital:
print(f"注册资本: {registered_capital.text.strip()}")
else:
print("未能获取注册资本信息!")
架构改进方案
- 动态加载应对策略:采用 Selenium / Playwright 等框架,模拟人类交互行为加载完整页面。
- 选择器稳定性保障:利用 XPath 表达式,结合多个属性定位元素;定期更新长效选择器库。
- 代理池搭建:引入多 IP 代理池,轮询使用不同 IP,提高请求成功率。
- 数据清洗与过滤:构建专用的数据清洗规则集,去除冗余、异常数据,提升数据质量。
总结
本次故障源于网页动态加载机制与选择器不匹配,辅以合理的代理 IP、请求头配置及动态加载调试工具,成功解决数据采集问题。在爬虫项目中,持续关注目标网站更新动态、优化选择器策略、升级反爬规避方案,是保障数据稳定性抓取的关键。