You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用BeautifulSoup爬取Yahoo Finance股票时Offset失效问题排查

问题描述

我想获取Yahoo Finance「被低估的成长型股票」页面表格里的所有股票列表,程序里尝试打印所有表格行的<a>标签,但每次只能输出前25条。我试着用while循环每次递增offset参数来获取后续25条数据,虽然offset确实在递增,但输出始终都是前25条表格行的<a>标签。

原代码

from bs4 import BeautifulSoup
import requests
import re

offset = 0
TableUrl = f"https://finance.yahoo.com/screener/predefined/undervalued_growth_stocks/?count=100&offset={offset}"
TablePage = requests.get(TableUrl).text
TableDoc = BeautifulSoup(TablePage, "html.parser")

# 统计股票总数
numOfStocksParent = TableDoc.find(class_="Mstart(15px) Fw(500) Fz(s)")
numOfStocks = int(numOfStocksParent.string.split("of ")[-1].split(" results")[0])

while offset < numOfStocks:
    LoopTableUrl = f"https://finance.yahoo.com/screener/predefined/undervalued_growth_stocks/?count=100&offset={offset}"
    LoopTablePage = requests.get(LoopTableUrl).text
    LoopTableDoc = BeautifulSoup(LoopTablePage, "html.parser")

    LoopTable = LoopTableDoc.find("table")
    LoopTableRows = LoopTable.find_all("tr")
    for row in LoopTableRows:
        print(row.find("a"))
    offset += 25
问题原因及解决办法

核心问题

Yahoo Finance的筛选页面依赖会话Cookie验证请求合法性,每次用requests.get()发起全新请求时,没有携带首次访问生成的Cookie,服务器会直接忽略offset参数,始终返回第一页数据。

修复方案

  1. 使用requests.Session()维持会话,自动保存和复用Cookie;
  2. 让count参数和递增步长保持一致(比如每次取25条就设count=25),避免数据重复或遗漏;
  3. 跳过表格表头行,避免输出空的<a>标签。

修复后的代码

from bs4 import BeautifulSoup
import requests
import re

# 初始化会话,自动维持Cookie
session = requests.Session()

offset = 0
# 首次请求获取股票总数,会话自动保存Cookie
TableUrl = f"https://finance.yahoo.com/screener/predefined/undervalued_growth_stocks/?count=25&offset={offset}"
TablePage = session.get(TableUrl).text
TableDoc = BeautifulSoup(TablePage, "html.parser")

# 提取股票总数
numOfStocksParent = TableDoc.find(class_="Mstart(15px) Fw(500) Fz(s)")
numOfStocks = int(numOfStocksParent.string.split("of ")[-1].split(" results")[0])

while offset < numOfStocks:
    LoopTableUrl = f"https://finance.yahoo.com/screener/predefined/undervalued_growth_stocks/?count=25&offset={offset}"
    LoopTablePage = session.get(LoopTableUrl).text
    LoopTableDoc = BeautifulSoup(LoopTablePage, "html.parser")

    LoopTable = LoopTableDoc.find("table")
    LoopTableRows = LoopTable.find_all("tr")
    # 跳过表头行,只遍历数据行
    for row in LoopTableRows[1:]:
        stock_link = row.find("a")
        if stock_link:
            # 打印股票代码和链接,替代原有的标签对象输出
            print(f"{stock_link.text}: {stock_link['href']}")
    offset += 25

补充说明

  • 会话session会自动保存首次请求的Cookie,后续请求携带该Cookie后,服务器就能正确识别offset参数,返回对应分页的数据;
  • 调整count与步长一致,确保每次请求刚好获取一页数据,避免重复抓取;
  • 跳过表头并判断链接是否存在,能避免输出空值,同时让输出内容更直观有用。

内容的提问来源于stack exchange,提问作者tdocog

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 10:55:35