使用Python和urllib从Yahoo财经获取数据

5 投票
4 回答
9769 浏览
提问于 2025-04-18 02:54

我在用Python的urllib库从雅虎财经获取股票价格。以下是我目前的代码:

import urllib
import re

name = raw_input(">")

htmlfile = urllib.urlopen("http://finance.yahoo.com/q?s=%s" % name)

htmltext = htmlfile.read()

# The problemed area 
regex = '<span id="yfs_l84_%s">(.+?)</span>' % name

pattern = re.compile(regex)

price = re.findall(pattern, htmltext)

print price

我输入一个值,然后股票价格就会显示出来。但是到现在为止,我只能显示一个价格,结果却是空白的[ ]。我在我认为有问题的地方加了注释。有什么建议吗?谢谢。

4 个回答

0

这篇指南会教你怎么构建Yahoo财经查询,这样你就能得到csv格式的数据。然后你可以用csv库轻松地解析这些数据。

如果你真的想尝试直接处理HTML,可以使用BeautifulSoup。用正则表达式处理HTML并不简单。

1

用python2或python3从Yahoo Finance获取数据的最好方法是使用POST方法。
你可以通过像Postman这样的Rest服务轻松测试一下这个方法。

打开Postman,选择POST方法,然后使用这个链接。这样你就能看到数据了。只需在python中重新创建这个过程。

import requests
url="https://query1.finance.yahoo.com/v7/finance/download/GOOG? period1=1519938930&period2=1522354530&interval=1d&events=history&crumb=.tLvYBkGDu3"

response = requests.post(url)
print response.text

我以前是用urllib2来获取数据的,但现在它出现了授权错误。
他们可能正在通过像GET和POST这样的Rest方法来过滤所有请求。

1

你有没有想过为什么不使用pandas呢?它对金融数据抓取和时间序列分析支持得很好。

http://pandas.pydata.org/pandas-docs/stable/remote_data.html

这里有一个来自文档的雅虎示例:

In [1]: import pandas.io.data as web
In [2]: import datetime
In [3]: start = datetime.datetime(2010, 1, 1)
In [4]: end = datetime.datetime(2013, 01, 27)
In [5]: f=web.DataReader("F", 'yahoo', start, end)
In [6]: f.ix['2010-01-04']
Out[6]: 
OnOpen               10.17
High               10.28
Low                10.05
Close              10.28
Volume       60855800.00
Adj Close           9.75
Name: 2010-01-04 00:00:00, dtype: float64
4

你在正则表达式中没有对斜杠进行转义。把你的正则表达式从:

<span id="yfs_l84_%s">(.+?)</span>

改成

<span id="yfs_l84_goog">(.+?)<\/span>

这样做可以解决你的问题,前提是你输入的内容是公司的上市代码。例如:输入goog代表谷歌。

不过,正则表达式并不是你想做的事情的好选择。正如其他人所建议的,试试 BeautifulSoup,这是一个用于从HTML中提取数据的Python库。使用BeautifulSoup,你的代码可以简单到:

from bs4 import BeautifulSoup
import requests

name = raw_input('>')
url = 'http://finance.yahoo.com/q?s={}'.format(name)
r = requests.get(url)
soup = BeautifulSoup(r.text)
data = soup.find('span', attrs={'id':'yfs_l84_'.format(name)})
print data.text

撰写回答