视频网站砸钱做生态,上海的公司名称,济南集团网站建设,企业网站建设报价表引言#xff1a; 在上篇博客中#xff0c;我们搞定了「沪深 300 当天实时数据」的爬取#xff0c;核心掌握了 GET 请求、JSONP 解析、多页循环这些入门技能。但实际应用中#xff0c;只看当天数据远远不够 —— 比如想分析一只股票的涨跌趋势、对比不同时间段的表现#x…引言在上篇博客中我们搞定了「沪深 300 当天实时数据」的爬取核心掌握了 GET 请求、JSONP 解析、多页循环这些入门技能。但实际应用中只看当天数据远远不够 —— 比如想分析一只股票的涨跌趋势、对比不同时间段的表现甚至做简单的投资参考都需要往期历史数据。这篇下篇就带大家 “适当的进阶”因为作者也能力有限不用复杂的 POST 负载基于上篇的基础逻辑做升级实现「按日期批量爬取往期数据」的核心需求。全程小白友好代码复制可运行重点解决 “怎么自动生成日期、跳过非交易日、稳定爬取多日期数据” 三大问题看完就能直接套用爬取任意时间段的沪深 300 数据目录一、上下篇对照二、前置准备三、核心原理2. 怎么避免 URL 过期3. 怎么稳定爬取多日期数据四、分步实操第一步生成日期列表 跳过非交易日第二步动态构造 URL避免过期第三步批量收集数据第四步自动创建目录 导出 Excel五、完整可运行代码六、小白必看1. 替换 Headers 中的 Cookie 和 User-Agent2. 修改保存目录七、避坑指南八、核心知识点总结一、上下篇对照功能维度上篇当天实时数据下篇往期批量数据数据范围仅当天 1 个日期支持自定义日期范围如 2025 年 1 月至今日期处理无需考虑日期参数自动生成日期列表 跳过周末非交易日URL 构造固定 callback 和时间戳动态生成 callback 时间戳避免过期数据存储单日期数据导出多日期数据汇总自动创建保存目录核心技能GET 请求 JSONP 解析日期循环 批量处理二、前置准备如果上篇已经安装过库直接跳过没安装的话终端输入以下命令pip install requests pandas openpyxl -i https://pypi.tuna.tsinghua.edu.cn/simple/requests发送网络请求核心pandas整理数据、导出 Excelopenpyxl支持 Excel 写入避免报错。三、核心原理1. 怎么让爬虫 “认识日期”我们需要先生成一个「日期列表」比如 2025 年 12 月 1 日到今天让爬虫按列表逐个日期爬取。关键是用datetime模块生成连续日期自动判断周末周六、周日是股市休市日直接跳过避免爬取无效数据。2. 怎么避免 URL 过期上篇的callback和_参数是固定的容易失效。下篇优化为动态生成callback字符串用当前时间戳拼接模拟浏览器实时请求_参数用当前时间戳每次请求都自动更新再也不用担心过期。3. 怎么稳定爬取多日期数据多日期 多页爬取容易出现 “某一页报错导致整个程序崩溃”所以要加多层try-except捕获异常请求失败、JSON 解析错误都不会让程序停出错后延迟 3 秒再继续避免频繁请求被反爬爬取每一页后延迟 1 秒控制请求频率。四、分步实操第一步生成日期列表 跳过非交易日先让爬虫知道 “要爬哪些日期”自动过滤周末休市日from datetime import datetime, timedelta # 1. 自定义爬取日期范围小白可直接修改这里 start_date datetime(2025, 12, 1) # 开始日期2025年12月1日 end_date datetime.now() # 结束日期今天自动获取不用改 # 2. 生成连续日期列表格式YYYYMMDD如20251201 date_list [] current_date start_date while current_date end_date: date_list.append(current_date.strftime(%Y%m%d)) # 转为接口需要的日期格式 current_date timedelta(days1) # 日期1天 # 3. 自动跳过周末非交易日 for date_str in date_list: date_obj datetime.strptime(date_str, %Y%m%d) if date_obj.weekday() 5: # 5周六6周日直接跳过 print(f跳过非交易日: {date_str}) continue # 后续爬取逻辑...小白注解只需修改 start_date 就能换爬取范围比如想爬 2025 年全年就改成 datetime(2025, 1, 1)。第二步动态构造 URL避免过期上篇的callback和时间戳是固定的下篇动态生成适配接口要求import time # 动态生成 callback 字符串模拟浏览器随机回调名 timestamp int(time.time() * 1000) # 当前时间戳毫秒级 callback_str fjQuery11240{int(time.time() * 1000)}_{timestamp - 30} # 随机拼接 # 构造 URL重点添加 date{date_str} 参数指定爬取日期 url (fhttp://4.push2.eastmoney.com/api/qt/clist/get?cb{callback_str} fpn{page}pz20po1np1utbd1d9ddb04089700cf9c27f6f7426281 ffltt2invt2wbp2u|0|0|0|webfidf3fsb:BK0500f:!50 ffieldsf1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f12,f13,f14,f15,f16,f17,f18,f20,f21,f23,f24,f25,f22,f11,f62,f128,f136,f115,f152,f45 fseciddate{date_str} # 关键指定当前爬取的日期 f_{timestamp})小白注解date{date_str}是核心参数告诉接口 “我要爬哪一天的数据”这是实现往期数据爬取的关键第三步批量收集数据用一个大列表all_data存储所有日期、所有页面的数据每爬完一条股票数据就添加到列表中最后统一导出 Excel# 定义大列表存储所有日期的所有股票数据 all_data [] # 遍历每个日期已过滤非交易日 for date_str in date_list: # 遍历每个页码1-15页每页20条共300只股票 for page in range(1, 16): try: # 发送请求、解析JSONP数据和上篇一致新增异常处理 res requests.get(url, headersheaders, timeout10) # ... 中间JSONP解析逻辑和上篇一致... # 提取股票数据添加到大列表 for di in diff_data: stock_data { 日期: date_str, # 新增日期字段区分不同时间段数据 代码: di.get(f12, ), 名称: di.get(f14, ), 最新价/元: di.get(f2, ), # ... 其他字段和上篇一致 ... } all_data.append(stock_data) # 汇总数据 time.sleep(1) # 每页爬完休息1秒抗反爬 print(f{date_str}第{page}页爬取成功) except Exception as e: # 出错不崩溃打印错误信息后继续爬下一页 print(f{date_str}第{page}页爬取出错: {str(e)}) time.sleep(3) # 出错后多休息3秒避免被封 continue第四步自动创建目录 导出 Excel避免因 “保存目录不存在” 导致报错自动创建目录且文件名包含当前日期方便区分版本import os # 定义保存目录小白可修改为自己的路径比如D:\股票数据 save_dir r股票\库 if not os.path.exists(save_dir): os.makedirs(save_dir) # 目录不存在则自动创建 # 生成带日期的文件名如沪深300_202501至今_20251217.xlsx current_date datetime.now().strftime(%Y%m%d) save_path os.path.join(save_dir, f沪深300_202501至今_{current_date}.xlsx) # 导出Excel df pd.DataFrame(all_data) df.to_excel(save_path, Sheet1, indexFalse) print(f所有数据爬取完成共{len(all_data)}条记录保存路径{save_path})五、完整可运行代码import requests import json import time import re import pandas as pd from datetime import datetime, timedelta import os # -------------------------- 1. 配置爬取参数小白重点修改这里-------------------------- # 爬取日期范围start_date 改起始日期end_date 默认为今天不用动 start_date datetime(2025, 12, 1) # 起始日期2025年12月1日格式年,月,日 end_date datetime.now() # 结束日期当前日期自动获取 # 保存目录修改为自己想保存的路径如D:\股票数据 save_dir r股票\库 # 请求头必须替换成自己的 User-Agent 和 Cookie否则会爬失败 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, Cookie: qgqp_b_iddfc29624f92cdad68210e05891a19e24; st_si53708276698179; websitepoptg_show_time1701908501838; st_asidelete; HAListty-1-000300-%u6CAA%u6DF1300%2Cty-1-000001-%u4E0A%u8BC1%u6307%u6570%2Cty-0-300059-%u4E1C%u65B9%u8D22%u5BCC; st_pvi57866953581055; st_sp2023-12-07%2008%3A21%3A41; st_inirUrlhttps%3A%2F%2Fwww.baidu.com%2Flink; st_sn24; st_psi20231209123634486-113200301321-2633832308, Referer: http://quote.eastmoney.com/, Accept: */*, Accept-Encoding: gzip, deflate, Accept-Language: zh-CN,zh;q0.9 } # -------------------------- 2. 生成日期列表自动跳过周末非交易日-------------------------- date_list [] current_date start_date while current_date end_date: date_list.append(current_date.strftime(%Y%m%d)) # 转为 YYYYMMDD 格式 current_date timedelta(days1) # -------------------------- 3. 批量爬取多日期数据 -------------------------- all_data [] # 存储所有日期的股票数据 total_dates len(date_list) current_date_idx 1 for date_str in date_list: # 跳过周末周六5周日6 date_obj datetime.strptime(date_str, %Y%m%d) if date_obj.weekday() 5: print(f\n[{current_date_idx}/{total_dates}] 跳过非交易日: {date_str}) current_date_idx 1 continue print(f\n [{current_date_idx}/{total_dates}] 开始爬取{date_str}的数据 ) current_date_idx 1 # 爬取当前日期的1-15页数据 for page in range(1, 16): try: print(f正在爬取{date_str}的第{page}页数据) # 动态生成 callback 和时间戳避免URL过期 timestamp int(time.time() * 1000) callback_str fjQuery11240{int(time.time() * 1000)}_{timestamp - 30} # 构造带日期参数的URL url (fhttp://4.push2.eastmoney.com/api/qt/clist/get?cb{callback_str} fpn{page}pz20po1np1utbd1d9ddb04089700cf9c27f6f7426281 ffltt2invt2wbp2u|0|0|0|webfidf3fsb:BK0500f:!50 ffieldsf1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f12,f13,f14,f15,f16,f17,f18,f20,f21,f23,f24,f25,f22,f11,f62,f128,f136,f115,f152,f45 fseciddate{date_str} f_{timestamp}) # 发送请求超时10秒避免卡壳 res requests.get(url, headersheaders, timeout10) res.encoding utf-8 content1 res.text # 解析JSONP数据 pattern re.escape(callback_str) r\((.?)\) match re.search(pattern, content1) if not match: print(f{date_str}第{page}页数据格式不正确跳过) continue extracted_data match.group(1) clean_data re.sub(r}\);, , extracted_data) # 解析JSON避免格式错误崩溃 try: json1 json.loads(clean_data) except json.JSONDecodeError: print(f{date_str}第{page}页JSON解析错误跳过) continue # 检查数据是否存在 if data not in json1 or json1[data] is None: print(f{date_str}第{page}页没有数据结束该日期爬取) break data json1[data] if diff not in data or not data[diff]: print(f{date_str}第{page}页没有股票数据结束该日期爬取) break diff_data data[diff] # 提取每条股票数据添加到总列表 for di in diff_data: # 跳过缺少核心字段的无效数据 if f12 not in di or f14 not in di: continue stock_data { 日期: date_str, 代码: di.get(f12, ), 名称: di.get(f14, ), 最新价/元: di.get(f2, ), 涨跌幅/%: di.get(f3, ), 涨跌额/元: di.get(f4, ), 成交量/手: di.get(f5, ), 成交额/万元: di.get(f6, ), 振幅/%: di.get(f7, ), 最高/元: di.get(f15, ), 最低/元: di.get(f16, ), 今开/元: di.get(f17, ), 昨收/元: di.get(f18, ), 量比: di.get(f10, ), 换手率: di.get(f8, ), 市盈率(动态): di.get(f9, ), 市净率: di.get(f23, ) } all_data.append(stock_data) # 控制爬取速度避免反爬 time.sleep(1) print(f{date_str}第{page}页爬取成功累计收集{len(all_data)}条数据) except Exception as e: print(f{date_str}第{page}页爬取出错: {str(e)}) time.sleep(3) # 出错后延迟3秒再继续 continue # -------------------------- 4. 数据导出自动创建目录-------------------------- # 确保保存目录存在 if not os.path.exists(save_dir): os.makedirs(save_dir) print(f已自动创建保存目录{save_dir}) # 生成带当前日期的文件名 current_date datetime.now().strftime(%Y%m%d) save_path os.path.join(save_dir, f沪深300_202501至今_{current_date}.xlsx) # 转换为DataFrame并保存 df pd.DataFrame(all_data) df.to_excel(save_path, Sheet1, indexFalse) # 打印爬取结果总结 print(f\n 爬取完成 ) print(f爬取日期范围{start_date.strftime(%Y-%m-%d)} 至 {end_date.strftime(%Y-%m-%d)}) print(f共爬取有效交易日{total_dates - len([d for d in date_list if datetime.strptime(d, %Y%m%d).weekday() 5])} 天) print(f共收集股票数据{len(all_data)} 条) print(f数据保存路径{save_path})六、小白必看1. 替换 Headers 中的 Cookie 和 User-Agent原代码中的 Cookie 和 User-Agent 是示例数据可能已过期。按以下步骤获取自己的打开 Chrome 浏览器访问「东方财富网沪深 300 板块」按 F12 打开开发者工具 → 切换到 Network 选项卡刷新页面搜索get?cbjQuery找到目标请求点击请求 → 复制 Headers 中的「User-Agent」和「Cookie」替换代码中对应位置。2. 修改保存目录代码中的save_dir r股票\库是示例路径小白要改成自己电脑上的路径比如rC:\Users\你的用户名\Desktop\股票数据避免目录不存在导致报错。七、避坑指南常见报错原因分析解决方法状态码 403禁止访问Cookie/User-Agent 过期或缺失重新获取自己的 Cookie 和 User-Agent某日期某页爬取失败接口临时不稳定或请求频率过快不用管代码会自动跳过该页继续爬后续可单独补爬JSON 解析错误接口返回数据格式异常代码已加异常捕获跳过无效数据不影响整体保存时提示 “目录不存在”保存路径写错或文件夹未创建确保save_dir路径正确代码会自动创建目录数据重复 / 缺失日期范围设置错误或非交易日未过滤检查start_date是否正确代码已自动跳过周末八、核心知识点总结日期处理用datetime生成连续日期weekday()判断周末避免爬取无效数据动态参数动态生成callback和时间戳解决 URL 过期问题批量收集用大列表all_data汇总多日期数据最后统一导出效率更高稳定性优化多层try-except捕获异常延迟请求避免反爬爬取更稳文件操作用os模块自动创建目录避免保存报错。通过上篇 下篇的学习你已经掌握了「当天实时数据」和「往期批量数据」的爬取能力足以满足日常股票数据收集、简单趋势分析的需求。如果运行代码时遇到问题欢迎在评论区留言我会逐一解答 关注我后续还会分享股票数据可视化和简单分析的实战内容