下面我将为你提供一个详细的、分步的指南,从最简单的方法到更高级、更稳健的自动化方法。

利用网页源代码导出k线
(图片来源网络,侵删)

核心原理

网页上的K线图数据,无论是通过JavaScript动态加载还是直接写在HTML里,最终都会以某种结构化数据的形式存在于你的浏览器中,我们的目标就是找到这些数据,并将其提取出来。

主要有两种情况:

  1. 数据直接在HTML中:数据以JSON格式嵌入在<script>标签里,或者作为表格数据存在。
  2. 数据由JavaScript动态加载:网页初始加载时没有数据,浏览器运行JavaScript代码后,通过AJAX请求从服务器获取数据并渲染到图表上,这是目前绝大多数网站采用的方式。

手动复制粘贴(适用于简单情况)

这种方法最简单,但效率低,且不适用于动态加载的数据。

步骤:

  1. 打开目标网页(新浪财经的某只股票页面)。
  2. F12 键打开开发者工具。
  3. 切换到 “元素”“Elements” 标签页。
  4. Ctrl + F (或 Cmd + F) 搜索可能包含数据的标签,scriptdatajson 等。
  5. 仔细检查<script>标签,看看里面是否有类似 { "data": [ ... ] } 这样的JSON结构。
  6. 如果找到了,复制这段JSON字符串。
  7. 使用在线JSON格式化工具(如 JSON Formatter)将其整理成可读格式。
  8. 手动复制整理后的数据到Excel或文本文件中。

缺点:

  • 耗时耗力。
  • 对于动态加载的数据,此方法完全无效。

使用浏览器开发者工具(核心方法)

这是最关键、最强大的方法,可以解决大部分动态加载数据的问题,我们以Chrome浏览器为例。

目标: 找到K线数据的来源(API接口)。

步骤:

  1. 打开目标网站:我们以东方财富网的股票K线页为例:http://quote.eastmoney.com/sh600519.html (贵州茅台)。

  2. 打开开发者工具:按 F12,切换到 “网络”“Network” 标签页。

  3. 过滤请求类型:在过滤框中输入 fetchXHR (XMLHttpRequest),这两个是JavaScript进行异步网络请求的关键词,可以帮我们快速定位到数据请求。

  4. 刷新页面:按 F5 刷新页面,你会看到列表中出现了一些新的请求,这些请求很可能就是用来加载K线数据的。

  5. 分析请求:点击其中一个看起来最相关的请求(通常是 url 中包含 api, data, kline, bar 等关键词的)。

  6. 检查响应

    • 切换到 “标头”“Headers” 标签页,查看 Request URL,这就是获取数据的服务器地址。
    • 切换到 “响应”“Response” 标签页,这里就是服务器返回的原始数据,通常是 JSON 格式。
  7. 复制URL和请求参数

    • URL: https://push2.eastmoney.com/api/qt/stock/kline/get?
    • 查询参数: 在 Headers -> Query String Parameters 部分,你会看到类似这样的参数:
      • cb: jQuery112403... (回调函数名,可以忽略)
      • secid: 600519 (股票代码)
      • ut: fa5fd1943c7b386f172d6893dbfba10b (一个token,有时可能需要)
      • fields1: f1,f2,f3,f4,f5,f6 (字段1)
      • fields2: f51,f52,f53,f54,f55,f56,f57,f58,f59,f60,f61 (字段2)
      • klt: 101 (K线类型,101=日线,102=周线,103=月线)
      • fqt: 1 (前复权)
      • end: 20500101 (结束日期)
      • lmt: 120 (获取条数)

恭喜! 你已经找到了数据源,这个URL和参数组合,就是生成K线数据的“魔法公式”,你可以直接在浏览器地址栏里修改参数(kltlmt)并回车,就能看到不同的数据返回。


编写自动化脚本(实现真正导出)

一旦你找到了数据API(如上一步),你就可以用任何编程语言来自动获取数据,这里我们用最常用的 Python 作为例子。

所需库:

  • requests: 用于发送HTTP请求。
  • pandas: 用于处理和导出数据。
  • json: 用于解析JSON数据。

Python脚本示例:

import requests
import pandas as pd
import json
# 1. 确定目标API和参数 (从开发者工具中获取)
# 以东方财富网为例
url = "https://push2.eastmoney.com/api/qt/stock/kline/get"
# 贵州茅台的日线数据
params = {
    'cb': 'jQuery112403..._1712345678902', # 回调函数名,可以随便写一个或去掉
    'secid': '1.600519',                   # 1.沪市  0.深市 + 股票代码
    'ut': 'fa5fd1943c7b386f172d6893dbfba10b', # 可能需要保持不变或从网页获取
    'fields1': 'f1,f2,f3,f4,f5,f6',         # 基础字段: 日期, 开盘, 收盘, 最高, 最低, 成交量
    'fields2': 'f51,f52,f53,f54,f55,f56,f57,f58,f59,f60,f61', # 扩展字段
    'klt': '101',                          # 101=日线, 102=周线, 103=月线
    'fqt': '1',                            # 1=前复权
    'end': '20500101',                     # 结束日期
    'lmt': '120'                           # 获取条数
}
# 2. 发送HTTP请求
try:
    response = requests.get(url, params=params, timeout=10)
    response.raise_for_status()  # 如果请求失败 (404, 500), 则抛出异常
    data = response.text
    # 3. 解析JSON数据
    # 注意:返回的数据可能被包裹在一个回调函数中,如 "jQuery11240...( { ... } )"
    # 我们需要提取出中间的JSON部分
    json_start = data.find('(')
    json_end = data.rfind(')')
    if json_start != -1 and json_end != -1:
        json_str = data[json_start+1:json_end]
        stock_data = json.loads(json_str)
    else:
        # 如果没有回调函数,直接解析
        stock_data = json.loads(data)
    # 4. 提取并处理数据
    # 数据在 'data' -> 'klines' 列表中
    klines = stock_data.get('data', {}).get('klines', [])
    if not klines:
        print("未获取到K线数据")
    else:
        # 将字符串列表转换为DataFrame
        # 东方财富的K线数据格式: "日期,开盘,收盘,最高,最低,成交量,成交额..."
        df = pd.DataFrame([line.split(',') for line in klines], 
                         columns=['日期', '开盘', '收盘', '最高', '最低', '成交量', '成交额', '振幅', '涨跌幅', '涨跌额', '换手率'])
        # 将字符串类型的数值列转换为浮点数
        numeric_cols = ['开盘', '收盘', '最高', '最低', '成交量', '成交额', '振幅', '涨跌幅', '涨跌额', '换手率']
        for col in numeric_cols:
            df[col] = pd.to_numeric(df[col], errors='coerce')
        # 5. 导出数据
        # 导出到CSV
        df.to_csv('stock_kline_data.csv', index=False, encoding='utf-8-sig')
        print("数据已成功导出到 stock_kline_data.csv")
        # 导出到Excel
        df.to_excel('stock_kline_data.xlsx', index=False)
        print("数据已成功导出到 stock_kline_data.xlsx")
        # 打印前5行数据预览
        print("\n数据预览:")
        print(df.head())
except requests.exceptions.RequestException as e:
    print(f"网络请求失败: {e}")
except json.JSONDecodeError as e:
    print(f"JSON解析失败: {e}")
except Exception as e:
    print(f"发生未知错误: {e}")

重要注意事项和挑战

  1. 反爬虫机制

    • User-Agent:服务器可能会检查你的请求头,模拟浏览器访问可以绕过,在 requests.get() 中添加 headers={'User-Agent': 'Mozilla/5.0 ...'}
    • IP封禁:如果请求过于频繁,你的IP可能会被临时或永久封禁,可以考虑使用代理IP池。
    • 动态Token:像 ut 这样的参数可能是动态生成的,每次访问页面都会变,这种情况下,你需要先访问主页面,用正则表达式或其他方法从HTML中提取出这个token,然后再去请求数据。
  2. 数据格式变化:网站可能会随时更新其API或数据格式,这意味着你的脚本可能需要定期维护和更新。

  3. 法律和道德风险

    • 请遵守网站的 robots.txt 文件,这个文件规定了哪些页面可以爬取,哪些不可以。
    • 不要对服务器造成过大压力,频繁请求可能会影响网站正常运营,甚至导致法律纠纷,合理设置请求间隔(time.sleep(1))。
    • 数据仅用于个人研究和学习,切勿用于商业用途或非法活动。
方法 优点 缺点 适用场景
手动复制 无需编程,简单直接 效率极低,无法处理动态数据,容易出错 一次性、少量数据的快速获取
开发者工具 核心方法,能找到数据源头,是自动化的基础 需要手动操作,不直接导出 分析网站结构,定位API,为脚本编写做准备
自动化脚本 高效、可重复、可扩展,能处理大量数据 需要编程知识,可能遇到反爬虫问题 批量获取历史数据、实时监控、量化分析

推荐路径:

  1. 先用方法二(开发者工具) 找到你感兴趣网站的数据API。
  2. 如果数据量大或需要重复操作,再根据方法三的思路编写Python脚本。
  3. 如果遇到反爬虫问题,再考虑添加 headers、代理或处理动态token。

希望这个详细的指南能帮助你成功导出K线数据!