高效爬取东方财富网股票数据:从抓包分析到数据存储

📅 发布时间:2026/7/6 5:05:00 👁️ 浏览次数:
高效爬取东方财富网股票数据:从抓包分析到数据存储
1. 为什么你需要自己动手爬取股票数据如果你对股票投资或者数据分析感兴趣肯定遇到过这样的问题想分析一下某个板块的整体情况或者想批量获取几千只股票的最新行情但一个个去网站翻看、手动复制粘贴那简直是噩梦。市面上的数据接口要么收费不菲要么限制多多。这时候自己动手写个爬虫直接从源头获取数据就成了一个既经济又高效的解决方案。东方财富网作为国内领先的财经门户其行情中心的数据非常全面和及时是很多投资者和分析师的首选。但是它的网页结构对于直接爬取并不友好数据往往不是直接写在HTML里而是通过后台接口动态加载的。这就意味着你不能简单地用requests请求网页然后BeautifulSoup解析那样拿到的只是一个空壳。你需要像侦探一样去“抓包”分析找到真正传输数据的那个“后门”。别担心这个过程听起来复杂实际操作起来跟着我的步骤走你会发现其实挺有意思的。今天我就带你从零开始一步步拆解东方财富网的股票数据接口写一个稳定、高效的爬虫并把爬下来的数据整整齐齐地存到Excel里。无论你是Python新手还是有一定经验的开发者只要跟着做都能搞定。我踩过的坑、总结的技巧都会毫无保留地分享给你。2. 第一步像侦探一样抓包找到数据真身很多新手一开始就急着写代码结果对着空空如也的网页源代码干瞪眼。我们的第一步必须是搞清楚数据到底藏在哪里。这里要用到浏览器开发者工具这是前端开发和爬虫工程师的“瑞士军刀”。打开东方财富网的行情中心页面就是原始文章里提到的那个网址按下键盘上的F12或者右键点击页面选择“检查”开发者工具就出来了。我们需要的重点是Network网络标签页。打开它然后刷新一下页面你会看到一大堆请求文件有.js、.css、图片还有各种神秘的接口。怎么找到我们想要的那个呢有个小技巧在Network面板里找到Fetch/XHR或XHR这个过滤器并点击。这个过滤器会只显示网页通过Ajax技术动态加载数据的请求而股票数据正是通过这种方式加载的。刷新页面后列表里会出现几个请求它们的名字通常是一长串字母数字比如get?cbjQuery...这种格式。接下来我们需要一个个点开这些请求查看它们的Preview预览或Response响应标签页。当你点开一个请求在预览里看到了熟悉的股票代码、名称、价格、涨跌幅这些信息时恭喜你找到“真身”了记下这个请求的Headers请求头信息特别是它的Request URL请求网址。这个URL就是我们后续爬虫要攻击的目标。我实测下来东方财富的这个数据接口URL结构比较固定但里面包含了一些动态参数比如一个长长的回调函数名cbjQuery1124...以及时间戳_1703949729656。这些参数有些是必需的有些则可以简化。通过对比翻页时URL的变化我们可以找出规律。你会发现真正控制页码的参数是pn而控制板块的参数藏在fid和fs这两个参数里。理解了这个我们就掌握了打开数据宝库的钥匙。3. 解码URL参数让爬虫知道你要哪一页、哪个板块找到目标URL只是开始理解它的每一个参数才能让我们游刃有余。我们把抓包得到的那个长长URL拆开来看它其实是由一个基础地址加上一堆查询参数构成的。基础地址通常是https://[数字].push2.eastmoney.com/api/qt/clist/get前面的数字可能会变但功能一样。关键参数解读我帮你把重要的几个挑出来了pn: 这个最简单就是page number页码。你想爬第几页的数据就把它改成几。pz: 每页显示的数量默认是20。你可以尝试改大一点比如改成100但要注意服务器可能会有限制。fid和fs: 这是决定板块的核心参数fid通常表示数据类别比如f3是A股行情而fs是一串复杂的代码定义了具体的市场、板块和股票类型。比如m:0t:6,m:0t:80,m:1t:2,m:1t:23,m:0t:81s:2048这一串就代表了“沪深京A股”它其实是把上证、深证、北交所等多个条件组合在了一起。难道我们每次都要去抓包找这串“摩尔斯电码”吗当然不用。通过观察我们可以把常见板块的fs代码整理成一个字典这就是编程的智慧。原始文章里已经给出了一个很全的字典包含了沪深京A股、上证A股、创业板、科创板等主流板块。你完全可以把它直接复制到你的代码里用。cmd { 沪深京A股: f3fsm:0t:6,m:0t:80,m:1t:2,m:1t:23,m:0t:81s:2048, 上证A股: f3fsm:1t:2,m:1t:23, 深证A股: f3fsm:0t:6,m:0t:80, 北证A股: f3fsm:0t:81s:2048, 创业板: f3fsm:0t:80, 科创板: f3fsm:1t:23, # ... 其他板块 }这样当你想爬“创业板”的数据时程序就会自动使用对应的fs代码去拼接URL非常方便。这里有个细节要注意URL里符号在Python字符串里有时需要写成amp;来避免解析错误但在requests库的params参数里或者用f-string拼接时直接写就行。4. 处理“脏数据”搞定JSONP和反爬虫机制直接请求我们找到的URL拿到的响应内容并不是一个干净的JSON字符串而是一种叫做JSONPJSON with Padding的数据格式。这是网站常用的一种跨域数据获取技术同时也算是一道简单的反爬虫障碍。它看起来是这样的jQuery1124007675389012158473_1703949729655({...数据...});。我们需要的数据确实在那个花括号{}里但外面包裹了一层函数调用。我们的目标就是把这层外壳剥掉。原始文章里用了正则表达式去匹配和替换这个方法完全可行。但我这里再教你一个更直观、更不容易出错的方法字符串切片。既然我们知道数据是从第一个左花括号{开始到最后一个右花括号}结束忽略最后的分号和括号那我们直接找到这两个位置就行了。import requests import re url 你的目标URL response requests.get(url, headersheaders) raw_text response.text # 方法1正则表达式原始文章方法需注意转义 # left_data re.search(r^.*?(?\(), raw_text).group() # clean_text re.sub(left_data \(, , raw_text) # clean_text re.sub(\);, , clean_text) # 方法2字符串切片更推荐更稳健 # 找到第一个左花括号的位置 start_index raw_text.find({) # 找到最后一个右花括号的位置 end_index raw_text.rfind(}) 1 # 切片要包含这个字符所以1 # 截取中间部分 clean_text raw_text[start_index:end_index]用方法二你几乎不用担心正则表达式写错的问题。拿到干净的JSON文本后用json.loads(clean_text)就能把它变成Python字典这才是我们熟悉的操作。另外记得设置请求头User-Agent把自己伪装成一个正常的浏览器这是绕过基础反爬虫的必备操作。5. 构建健壮的爬虫核心循环、判断与异常处理现在获取一页数据、解析数据的方法我们都掌握了。接下来要做的就是让程序自动化地遍历所有页面和所有板块。这里需要一个双层循环外层循环遍历我们之前定义的板块字典内层循环针对每个板块从第1页开始不断请求直到没有数据为止。怎么判断没有数据了呢观察发现当你请求一个不存在的页码时比如某个板块只有100页你请求第101页返回的JSON数据里data字段的值会是null。注意这个null在JSON里是Python中的None但如果我们用eval()函数不推荐或遇到某些情况它可能是一个未定义的变量名。所以保险起见我们可以先定义一个null None或者在判断时直接使用if data.get(data):这种方式。一个健壮的核心爬取循环应该像下面这样import pandas as pd import time headers { User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 ... } all_data {} for board_name, board_code in cmd.items(): print(f开始爬取板块【{board_name}】) board_stocks [] page 1 while True: try: # 构建每一页的URL这里用params参数更清晰 params { pn: page, pz: 20, fid: board_code.split()[0], # 提取fid部分 fs: board_code.split()[1].replace(fs, ) if fs in board_code else board_code.split()[1], # ... 其他固定参数 } response requests.get(base_url, paramsparams, headersheaders) response.raise_for_status() # 检查请求是否成功 # 清洗数据转换为字典 data_dict parse_jsonp(response.text) # 假设parse_jsonp是清洗函数 if not data_dict.get(data): print(f {board_name} 共 {page-1} 页爬取完毕。) break # 提取diff列表 stock_list data_dict[data].get(diff, []) if not stock_list: break for item in stock_list: # 根据字段映射字典提取所需字段 stock_info { 代码: item.get(f12, ), 名称: item.get(f14, ), 最新价: item.get(f2, 0), # ... 其他字段 } board_stocks.append(stock_info) print(f 已爬取第 {page} 页累计 {len(board_stocks)} 条记录。) page 1 # 非常重要添加延迟避免请求过快被封IP time.sleep(1.5) except requests.exceptions.RequestException as e: print(f请求出错{e}正在重试...) time.sleep(5) # 出错后等待更长时间 except KeyError as e: print(f解析数据时出错键错误{e}可能数据结构有变。) break if board_stocks: all_data[board_name] pd.DataFrame(board_stocks)这段代码加入了异常处理try...except、请求状态检查、以及最重要的time.sleep()延迟。不加延迟地疯狂请求你的IP很快就会被网站封掉。睡个1-2秒既礼貌又安全。把爬取到的每个板块的数据先存到一个字典里最后再统一保存。6. 从数据字典到Excel用Pandas优雅地存储爬虫的最终目的是为了使用数据而Excel无疑是大多数人最熟悉的数据交换格式。Python的Pandas库让这个步骤变得异常简单。当我们把每个板块的数据都转换成Pandas的DataFrame对象后保存就是一行代码的事。但是直接保存可能会遇到两个小问题一是中文乱码二是数据格式比如数字被存成了文本。我们可以通过设置to_excel方法的参数来解决。# 假设 all_data 是一个字典键是板块名值是DataFrame with pd.ExcelWriter(东方财富股票数据汇总.xlsx, engineopenpyxl) as writer: for board_name, df_board in all_data.items(): # 简单清洗确保列顺序处理空值 df_board df_board.fillna(N/A) # 将空值填充为N/A # 保存到Excel的不同Sheet中 df_board.to_excel(writer, sheet_nameboard_name[:31], indexFalse) # sheet名不能超31字符 print(所有数据已成功保存到 东方财富股票数据汇总.xlsx 文件中。)这里我用了pd.ExcelWriter作为上下文管理器它可以把多个DataFrame一次性写入一个Excel文件的不同工作表Sheet里非常整洁。indexFalse参数是为了不把DataFrame的行索引也保存进去。engineopenpyxl是为了更好地支持新版.xlsx文件。保存完之后你可以打开Excel文件检查一下。如果发现数字代码如‘000001’前面的0被删掉了那是因为Pandas默认把这类列识别成了数字。你需要在构建DataFrame前就将代码列强制转换为字符串类型代码: str(item.get(f12, ))。7. 实战进阶让爬虫更强大、更稳定基本的爬虫跑起来后我们可以考虑把它变得更专业、更抗造。这里分享几个我实战中总结的进阶技巧。第一应对反爬虫。东方财富网这类大型网站肯定有反爬机制。除了设置User-Agent你还可以考虑使用IP代理池如果你的请求量非常大单一IP容易被封。可以找一些可靠的代理IP服务在请求时随机切换。使用Session对象requests.Session()可以保持会话自动处理cookies有时比单次请求更稳定。随机延迟将固定的time.sleep(2)改为time.sleep(random.uniform(1, 3))让请求间隔时间更随机更像真人操作。第二优化代码结构。把功能模块化比如把发送请求和解析JSONP的函数单独写出来这样主逻辑会更清晰也方便调试和维护。第三添加日志功能。不要只用print使用Python的logging模块记录信息、警告和错误。这样当爬虫在后台运行时你可以通过查看日志文件来了解运行状态和排查问题。第四考虑增量爬取。如果你需要每天更新数据每次都全量爬取几千只股票效率太低。可以设计一个逻辑只爬取当天有更新的数据比如通过对比最后更新时间字段。这需要对数据接口和字段有更深入的研究。最后一定要尊重网站。在爬虫的请求头里可以加上Referer通常设为目标网站首页表明请求的来源。控制请求频率尽量在非交易时段如深夜、周末进行大规模爬取减少对网站服务器的压力。技术是工具合理合法地使用它才是长久之道。写爬虫就像搭积木从最简单的请求开始逐步添加错误处理、延迟、数据清洗、存储等模块。过程中可能会遇到各种意想不到的返回格式或错误耐心分析、逐个解决你的爬虫技能就会在这个过程中飞速成长。希望这篇详细的指南能帮你顺利拿到想要的数据为你的投资分析或数据项目打下坚实的基础。如果在实际操作中遇到任何问题欢迎随时来交流讨论。