数据爬虫:获取申万一级行业数据

'# 数据爬虫:获取申万一级行业数据

一、背景与问题

在金融数据分析领域,申万一级行业分类体系是重要的参考标准。该分类体系将中国A股市场划分为28个一级行业(如医药生物、电子、机械设备等),每个行业包含若干二级子类。获取该分类体系的数据对于构建行业分析模型、研究市场趋势具有重要意义。

但实际开发中面临以下挑战:

  1. 目标网站可能部署反爬虫机制
  2. 数据存储结构需要规范化处理
  3. 动态加载内容的处理
  4. 法律合规性问题
  5. 大规模数据抓取时的性能优化

二、基本原理

申万行业分类数据通常存在于金融数据网站(如同花顺、东方财富)的行业分类页面中。其获取过程包含以下核心步骤:

  1. 网络请求:通过HTTP协议向目标网站发送请求,获取网页内容
  2. 页面解析:使用HTML解析库提取目标数据
  3. 数据清洗:去除冗余信息,构建标准数据结构
  4. 存储管理:将数据持久化存储到数据库或文件

在技术实现中需特别注意:

  • 需处理目标网站的反爬虫机制(如验证码、IP封禁)
  • 需处理动态加载内容(如通过JavaScript生成的DOM)
  • 需遵循网站的robots.txt规则
  • 需考虑法律合规性(如《网络安全法》第27条)

三、环境准备

# 安装必要库
pip install requests beautifulsoup4 selenium lxml
# 安装浏览器驱动(以Chrome为例)
# 下载对应版本的chromedriver
# https://chromedriver.chromium.org/

四、核心实现

1. 静态页面解析示例

import requests
from bs4 import BeautifulSoup

def fetch_static_data():
    url = "https://www.10jqka.com.cn/industry/"
    headers = {
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4441.40 Safari/537.36"
    }
    
    response = requests.get(url, headers=headers)
    soup = BeautifulSoup(response.text, 'lxml')
    
    # 提取行业名称和代码
    industries = []
    for item in soup.select('.industry-list li'):
        code = item.select_one('.code').text.strip()
        name = item.select_one('.name').text.strip()
        industries.append({
            "code": code,
            "name": name
        })
    
    return industries

关键代码解释:

  • 使用requests发送HTTP请求,设置合理的User-Agent避免被识别为爬虫
  • 使用BeautifulSoup解析HTML文档,选择器.industry-list li定位行业条目
  • 提取.code和.name两个类的文本内容,构建标准数据结构

2. 动态内容处理示例

from selenium import webdriver
from selenium.webdriver.chrome.options import Options

def fetch_dynamic_data():
    chrome_options = Options()
    chrome_options.add_argument("--headless")  # 无头模式
    chrome_options.add_argument("--disable-gpu")
    chrome_options.add_argument("--no-sandbox")
    
    driver = webdriver.Chrome(options=chrome_options)
    url = "https://www.10jqka.com.cn/industry/"
    driver.get(url)
    
    # 等待动态内容加载
    driver.implicitly_wait(10)
    
    # 提取动态生成的内容
    industries = []
    for item in driver.find_elements_by_css_selector('.industry-list li'):
        code = item.find_element_by_class_name('code').text.strip()
        name = item.find_element_by_class_name('name').text.strip()
        industries.append({
            "code": code,
            "name": name
        })
    
    driver.quit()
    return industries

关键代码解释:

  • 使用Selenium启动无头浏览器,模拟真实用户操作
  • 通过implicitly_wait等待动态内容加载完成
  • 使用CSS选择器获取动态生成的DOM节点
  • 注意处理可能的元素定位异常

3. 数据存储示例

import sqlite3

def save_to_sqlite(data):
    conn = sqlite3.connect('industries.db')
    cursor = conn.cursor()
    
    # 创建表(如果不存在)
    cursor.execute('''
        CREATE TABLE IF NOT EXISTS industries (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            code TEXT NOT NULL,
            name TEXT NOT NULL,
            created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
        )
    ''')
    
    # 插入数据
    cursor.executemany('''
        INSERT INTO industries (code, name) VALUES (?, ?)
    ''', [(item['code'], item['name']) for item in data])
    
    conn.commit()
    conn.close()

关键代码解释:

  • 使用SQLite存储数据,保证数据持久化
  • 通过CREATE TABLE IF NOT EXISTS避免重复创建表
  • 使用参数化查询防止SQL注入
  • 自动记录创建时间戳

五、完整案例

1. 完整爬虫流程

def main():
    # 获取数据
    industries = fetch_dynamic_data()
    
    # 存储数据
    save_to_sqlite(industries)
    
    # 输出结果
    for item in industries:
        print(f"{item['code']}: {item['name']}")

if __name__ == "__main__":
    main()

2. 运行结果示例

001: 食品饮料
002: 医药生物
003: 医疗器械
...

3. 关键注意事项

  • 需处理可能的网络异常(超时、连接错误)
  • 需处理动态内容加载的等待时间
  • 需处理浏览器驱动版本兼容性
  • 需处理可能的反爬虫机制(如验证码)

六、源码解析

1. 反爬虫机制处理

headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4441.40 Safari/537.36",
    "Referer": "https://www.10jqka.com.cn/"
}
  • 设置合理的User-Agent,模拟真实浏览器
  • 添加Referer头,避免被服务器识别为爬虫
  • 可添加随机的请求间隔(sleep(1-3))防止触发风控

2. 动态内容处理优化

driver.implicitly_wait(10)  # 设置等待时间
  • 使用隐式等待代替显式等待,更灵活
  • 可结合WebDriverWait实现更精确的等待
  • 注意避免过度等待影响性能

3. 数据清洗处理

def clean_data(data):
    return [item for item in data if item['code'] and item['name']]
  • 过滤空数据,保证数据完整性
  • 可添加正则表达式校验数据格式
  • 可使用Pandas进行更复杂的数据清洗

七、进阶使用

1. 多线程爬虫

from concurrent.futures import ThreadPoolExecutor

def fetch_data_with_threads():
    with ThreadPoolExecutor(max_workers=5) as executor:
        results = executor.map(fetch_dynamic_data, ["" for _ in range(5)])
    
    # 合并结果
    all_data = []
    for result in results:
        all_data.extend(result)
    
    save_to_sqlite(all_data)

2. 代理IP池使用

proxies = {
    "http": "http://10.10.1.10:3128",
    "https": "http://10.10.1.10:1080"
}

response = requests.get(url, headers=headers, proxies=proxies)

3. 异常处理机制

try:
    response = requests.get(url, headers=headers, timeout=10)
    response.raise_for_status()
except requests.exceptions.RequestException as e:
    print(f"请求异常: {e}")
    return []

八、性能与工程实践

1. 性能优化策略

优化策略说明
压缩请求使用gzip压缩传输数据
并行处理使用线程池或异步IO
缓存机制使用Redis缓存常见结果
限流控制设置合理的请求间隔

2. 异常处理规范

  • 网络异常:重试机制 + 限流
  • 数据异常:校验规则 + 日志记录
  • 系统异常:熔断机制 + 降级处理
  • 安全异常:访问控制 + 日志审计

3. 安全风险分析

风险类型风险描述解决方案
被封IP频繁请求触发风控使用代理IP池
验证码识别需要人工干预使用第三方验证码识别服务
数据泄露未加密传输使用HTTPS协议
法律风险违反《网络安全法》确保合法授权

九、常见问题与踩坑

1. 常见错误及解决

错误示例:

# 错误的请求方式
response = requests.get(url)

问题分析:

  • 缺少User-Agent导致被拒绝
  • 未处理可能的异常

改进方案:

headers = {
    "User-Agent": "Mozilla/5.0 ..."
}
response = requests.get(url, headers=headers, timeout=10)
response.raise_for_status()

2. 动态内容处理陷阱

错误示例:

# 错误的元素定位
elements = driver.find_elements_by_css_selector('.industry-list')

问题分析:

  • 未等待动态内容加载完成
  • 选择器不准确

改进方案:

from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

elements = WebDriverWait(driver, 10).until(
    EC.presence_of_element_located((By.CSS_SELECTOR, '.industry-list'))
)

十、最佳实践

1. 推荐方案

场景推荐方案说明
静态页面requests + BeautifulSoup轻量级快速开发
动态页面Selenium处理复杂交互
大规模数据Scrapy高性能分布式爬虫
法律合规本地化部署避免外部依赖

2. 实际应用建议

  • 对于金融数据爬取,建议使用本地化部署方案
  • 建议使用分布式爬虫框架处理大规模数据
  • 需建立完善的日志系统和监控机制
  • 建议定期更新User-Agent池

十一、总结

获取申万一级行业数据是金融数据分析的重要环节,需要综合运用网络请求、页面解析、动态处理、数据存储等技术。本文通过三个代码示例展示了完整的爬虫流程,重点分析了反爬虫机制、动态内容处理、性能优化等关键问题。

在实际开发中,应根据具体需求选择合适的方案:

  • 使用requests和BeautifulSoup处理静态页面
  • 使用Selenium处理动态内容
  • 使用Scrapy进行大规模数据抓取

同时需注意法律合规性,遵守网站的robots.txt规则,合理使用代理IP池,建立完善的异常处理机制。对于涉及敏感数据的场景,建议采用本地化部署方案,确保数据安全和法律合规。

通过合理的设计和优化,可以构建稳定、高效的爬虫系统,为金融数据分析提供可靠的数据支持。

none
最后修改于:2026年10月01日 16:07

评论已关闭

推荐阅读

AIGC实战——Transformer模型
2024年12月01日
Socket TCP 和 UDP 编程基础(Python)
2024年11月30日
python , tcp , udp
如何使用 ChatGPT 进行学术润色?你需要这些指令
2024年12月01日
AI
最新 Python 调用 OpenAi 详细教程实现问答、图像合成、图像理解、语音合成、语音识别(详细教程)
2024年11月24日
ChatGPT 和 DALL·E 2 配合生成故事绘本
2024年12月01日
omegaconf,一个超强的 Python 库!
2024年11月24日
【视觉AIGC识别】误差特征、人脸伪造检测、其他类型假图检测
2024年12月01日
[超级详细]如何在深度学习训练模型过程中使用 GPU 加速
2024年11月29日
Python 物理引擎pymunk最完整教程
2024年11月27日
MediaPipe 人体姿态与手指关键点检测教程
2024年11月27日
深入了解 Taipy:Python 打造 Web 应用的全面教程
2024年11月26日
基于Transformer的时间序列预测模型
2024年11月25日
Python在金融大数据分析中的AI应用(股价分析、量化交易)实战
2024年11月25日
AIGC Gradio系列学习教程之Components
2024年12月01日
Python3 `asyncio` — 异步 I/O,事件循环和并发工具
2024年11月30日
llama-factory SFT系列教程:大模型在自定义数据集 LoRA 训练与部署
2024年12月01日
Python 多线程和多进程用法
2024年11月24日
Python socket详解,全网最全教程
2024年11月27日
python之plot()和subplot()画图
2024年11月26日
理解 DALL·E 2、Stable Diffusion 和 Midjourney 工作原理
2024年12月01日