当前位置:首页>python>量化系列(七十八) Python 三分钟抓取同花顺板块实时数据|附可直接运行完整源码

量化系列(七十八) Python 三分钟抓取同花顺板块实时数据|附可直接运行完整源码

  • 2026-09-05 03:04:47
量化系列(七十八) Python 三分钟抓取同花顺板块实时数据|附可直接运行完整源码

一. 读完这一章节,你能收获什么?

上一章节我们获取到了同花顺的板块数据,这一章节,我们可以获取板块的今日K线数据, 包括涨跌幅,开盘价,收盘价,最高价,最低价等。 拥有了这些数据,我们就可以对一个某一个板块进行分析,甚至是 AI预测了。

这一章节,也采用 Python 的写法进行获取数据,采用 Java 的写法进行解析数据。

本文含系统自动匹配的广告,广告收入用于支持持续创作,感谢理解

二. 上一章节内容补充

有不少读者反馈, 板块数据写的不错, 但没有概念和地区数据的爬取。   其实 概念,地区 和板块三者的处理是完全一致的, 只不过页面 url 不一样。

板块的地址是:

https://q.10jqka.com.cn/thshy/

概念是:

https://q.10jqka.com.cn/gn/

地区是:

https://q.10jqka.com.cn/dy/

其中,概念在爬取时, 因为数据量较多, 需要先显示全部

其它的处理上都是一致的。

大家可以举一反三一下,如果有问题的话,可以私信联系我。

三. 如何获取板块的实时数据?

我们先进入板块的页面:

https://q.10jqka.com.cn/thshy/

我们任意点击一个板块,如 能源金属

会跳转到 能源金属的页面

地址样式是:

https://q.10jqka.com.cn/thshy/detail/code/881267/

其中  881267  对应的就是  板块的编码。   同花顺的板块编码都是  88 开头的

点击 F12 查看请求,会发现 有这样一个 js 请求

https://d.10jqka.com.cn/v4/line/bk_881267/01/today.js

其中  today.js 对应的 就是 今日的行情数据,  01 表示 日K 类型。

对应的内容是:

quotebridge_v4_line_bk_881267_01_today({"bk_881267":{"1":"20260624","7":"37911.539","8":"40001.052","9":"37441.401","11":"39856.935","13":502671250,"19":"29001399000.000","74":"","1968584":"","66":"","open":0,"dt":"1734","name":"\u80fd\u6e90\u91d1\u5c5e","marketType":""}})

其中字段对应的解释如下:

字段
解释
name
名称
1
日期   yyyyMMdd 格式
7
开盘价
8
最高价
9
最低价
11
收盘价(最新价)
13
成交量
19
成交金额

获取了这一个文件,我们就能获取这 90个板块的数据,  并且将他们保存到  今K  这个文件夹下。    其中,板块的数据,从上一章节中的文件里面进行获取。

四.   批量下载板块日K文件数据

知道了上面的 今K 的 数据文件的  url  那么就变成了 一个 文件下载的脚本了。

四. 一   先生成批量的 URL

import csvimport reimport os# ===================== 配置项 =====================INPUT_CSV = "ths_bk.csv"       # 输入文件:板块url+名称OUTPUT_CSV = "ths_bk_nowdataUrl.csv" # 输出文件:编码+日/周/月K线地址# 正则提取url中code后的6位数字编码CODE_PATTERN = re.compile(r'code/(\d{6})')# K线地址模板URL_TEMPLATE = "https://d.10jqka.com.cn/v4/line/bk_{code}/01/today.js"# ==================================================# 读取输入文件,处理数据output_data = []with open(INPUT_CSV, "r", encoding="utf-8-sig") as f:    reader = csv.DictReader(f)    for row in reader:        # 读取url和名称        bk_url = row.get("url", "").strip()        bk_name = row.get("name", "").strip()        # 提取6位编码        match = CODE_PATTERN.search(bk_url)        if not match:            print(f"跳过无效链接(无6位编码):{bk_name} | {bk_url}")            continue        bk_code = match.group(1)        # 生成日/周/月K线地址        day_k = URL_TEMPLATE.format(code=bk_code, type="01")        # 加入输出列表        output_data.append([bk_code, day_k])        print(f"处理完成:{bk_code} {bk_name}")# 写入输出CSV文件with open(OUTPUT_CSV, "w", newline="", encoding="utf-8-sig") as f:    writer = csv.writer(f)    # 写入表头    writer.writerow(["编码", "今K"])    # 写入数据    writer.writerows(output_data)print(f"\n✅ 全部处理完成!共生成 {len(output_data)} 条数据")print(f"📁 文件已保存至:{os.path.abspath(OUTPUT_CSV)}")

会生成对应的   ths_bk_nowdataUrl.csv

四.二   批量下载今日K数据

import csvimport osimport timeimport requests# ===================== 配置 =====================INPUT_CSV = "ths_bk_nowdataUrl.csv"SLEEP_SECONDS = 5  # 每个文件下载后休眠5秒HEADERS = {    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",    "Referer": "https://d.10jqka.com.cn/"}# ==================================================# 创建 日K 周K 月K 文件夹os.makedirs("今K", exist_ok=True)# 下载函数def download_file(url, save_path):    try:        print(f"正在下载: {url}")        resp = requests.get(url, headers=HEADERS, timeout=15)        resp.raise_for_status()        with open(save_path, "w", encoding="utf-8") as f:            f.write(resp.text)        print(f"✅ 保存成功: {save_path}")    except Exception as e:        print(f"❌ 下载失败: {url} => {e}")# 读取 CSV 并开始下载with open(INPUT_CSV, "r", encoding="utf-8-sig") as f:    reader = csv.DictReader(f)    for row in reader:        code = row["编码"].strip()        day_url = row["今K"].strip()        print(f"\n===== 开始处理板块编码: {code} =====")        # 下载 日K        download_file(day_url, f"今K/{code}.js")        time.sleep(SLEEP_SECONDS)print("\n🎉 所有文件下载完成!")

五.   Java 解析文件并入库

现在文件已经下载到本地了,接下来,可以将这些数据进行入库, 入到  bk_history 表里面。

    @PostMapping("/importNowKlineData")    @Operation(summary = "导入所有的同花顺今日数据")    public void importNowKlineData() {        //今K        thsDataBusiness.processNowDir(new File(BASE_PATH + File.separator + "今K"), 1, 1);        log.info("=====全部日K线导入完成=====");    }
/**     * @param dir 文件目录     * @param type 板块类型固定1     * @param kType 今K     */    public void processNowDir(File dir, Integer type, int kType) {        if (!dir.exists()) {            log.warn("目录不存在:{}", dir.getAbsolutePath());            return;        }        File[] jsFiles = dir.listFiles(f -> f.getName().endsWith(".js"));        if (jsFiles == null || jsFiles.length == 0) return;        for (File file : jsFiles) {            String fileName = file.getName();            //截取编码 881284.js → 881284            String bkCode = fileName.replace(".js", "");            log.info("开始解析板块:{}", bkCode);            try {                //读取文件全量文本                String content = Files.readString(file.toPath(), StandardCharsets.UTF_8);                //截取括号内部json字符串 去掉函数包裹 quotebridge_v4_line_bk_xxx_last( {json} )                int left = content.indexOf("(");                int right = content.lastIndexOf(")");                String jsonStr = content.substring(left + 1, right).trim();                JSONObject fullJson = JSONObject.parseObject(jsonStr);                JSONObject json = fullJson.getJSONObject("bk_"+bkCode);                //日期 yyyyMMdd                Date currDate = sdfIn.parse(json.getString("1"));                BigDecimal open = new BigDecimal(json.getString("7"));                BigDecimal high = new BigDecimal(json.getString("8"));                BigDecimal low = new BigDecimal(json.getString("9"));                BigDecimal close = new BigDecimal(json.getString("11"));                BigDecimal vol = new BigDecimal(json.getString("13"));                BigDecimal amount = new BigDecimal(json.getString("19"));                BkHistoryDo bkHistoryDo = bkHistoryDomainService.getLastByCode(bkCode);                BkHistoryDo newBkHistoryDo = new BkHistoryDo();                newBkHistoryDo.setCode(bkCode);                newBkHistoryDo.setName(bkHistoryDo.getName());                newBkHistoryDo.setCurrDate(MyDateUtil.fillTime(currDate));                newBkHistoryDo.setType(type);                newBkHistoryDo.setOpeningPrice(open);                newBkHistoryDo.setHighestPrice(high);                newBkHistoryDo.setLowestPrice(low);                newBkHistoryDo.setClosingPrice(close);                newBkHistoryDo.setYesClosingPrice(bkHistoryDo.getClosingPrice());                newBkHistoryDo.setAmplitude(BigDecimalUtil.sub4(                        close,                        bkHistoryDo.getClosingPrice()                ));                newBkHistoryDo.setAmplitudeProportion(                        BigDecimal.valueOf(BigDecimalUtil.subAndDivAndMul100(                                close,                                bkHistoryDo.getClosingPrice()                        ))                );                newBkHistoryDo.setTradingVolume(vol);                newBkHistoryDo.setTradingValue(amount);                bkHistoryDomainService.save(newBkHistoryDo);                // 保存到 周K里面                stockHistoryHelper.updateBkWeekHistory(newBkHistoryDo);                stockHistoryHelper.updateBkMonthHistory(newBkHistoryDo);            } catch (Exception e) {                log.error("文件{}解析失败",fileName,e);            }        }    }

之后,就可以在 bk_history 中 查看今天的 板块日K 数据了。

免责声明:本文仅供技术交流,不构成任何投资建议。股市有风险,投资需谨慎。

如果你觉得这篇文章说到了心坎里,请点个“在看”,点个关注,并转发给身边的朋友,让更多人支持小亥!

#金亥跃江 #金亥跃江聊量化#股票量化 #同花顺板块

最新文章

随机文章