You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何用Python和Xpath爬取雅虎财经5天股票历史价格?

解决重复获取首日股价的问题

你遇到的核心问题是代码里的URL根本没随着日期变化——你的start_url没有预留格式化占位符(比如{}),所以url = start_url.format(start.strftime("%Y%m%d"))这一行完全没生效,每次循环请求的都是同一个当前报价页面,自然输出的都是同一天的价格。

下面给你两种可行的修改方案,按需选择:

方案一:一次性获取过去5天数据(更高效)

直接请求股票的历史数据页面,一次性提取时间范围内的所有日线数据,避免多次请求:

import requests
from lxml import html
from datetime import datetime, timedelta

# 计算时间范围:取最近7天(多留2天排除周末/节假日休市)
end_date = datetime.now()
start_date = end_date - timedelta(days=7)
# 转换为Unix时间戳(Yahoo Finance接口需要)
period1 = int(start_date.timestamp())
period2 = int(end_date.timestamp())

# 构造历史数据页面URL
url = f"https://in.finance.yahoo.com/quote/HINDUNILVR.NS/history?period1={period1}&period2={period2}&interval=1d&filter=history&frequency=1d&includeAdjustedClose=true"

page = requests.get(url)
tree = html.fromstring(page.content)

# 提取历史表格中的收盘价(XPath对应页面结构,若页面更新需微调)
rows = tree.xpath('//table[@data-test="historical-prices"]/tbody/tr')
prices = []
for row in rows[:5]:
    close_price = row.xpath('./td[5]/span/text()')  # 第5列对应收盘价
    if close_price:
        prices.append(close_price)

# 输出结果
for price in prices:
    print(price)

方案二:循环请求单个日期数据(贴合你的原始思路)

如果坚持要按天循环请求,需要构造每个日期对应的历史数据URL,确保每次请求的页面是对应日期的:

import requests
from lxml import html
from datetime import datetime,timedelta

# 起始日期(替换成你需要的开始日期)
start = datetime(2024, 5, 20)
prices = []

for _ in range(5):
    # 构造单个日期的历史数据URL:只请求当天的范围
    period1 = int(start.timestamp())
    period2 = int((start + timedelta(days=1)).timestamp())
    url = f"https://in.finance.yahoo.com/quote/HINDUNILVR.NS/history?period1={period1}&period2={period2}&interval=1d&filter=history&frequency=1d&includeAdjustedClose=true"
    
    page = requests.get(url)
    tree = html.fromstring(page.content)
    
    # 提取当天收盘价
    close_price = tree.xpath('//table[@data-test="historical-prices"]/tbody/tr/td[5]/span/text()')
    if close_price:
        prices.append(close_price[0])
    
    # 日期往前推一天
    start -= timedelta(days=1)

# 反转列表,让结果按从新到旧的顺序展示
prices.reverse()
print([[price] for price in prices])

注意事项

  • Yahoo Finance的页面结构可能会更新,如果XPath提取不到数据,需要打开页面检查元素,调整XPath路径。
  • 股市在周末、节假日休市,这些日期不会有数据,代码里加了空值判断避免报错。

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

火山引擎 最新活动