解析CSV文件以制作股票代码数据图表
解析CSV文件以制作股票代码数据图表
我创建了一个程序,它接收股票代码,爬取网页以找到每个股票代码的历史价格的CSV文件,并使用matplotlib进行绘图。几乎一切都运行正常,但我遇到了一个解析CSV文件以分离出每个价格的问题。
我遇到的错误是:
prices = [float(row[4]) for row in csv_rows]
IndexError: list index out of range
我知道问题出在哪里,但我不太确定应该如何修复它。
(问题在于parseCSV()
方法)
# 循环绘制多个股票图表 def chartStocks(*tickers): for ticker in tickers: chartStock(ticker) # 单个绘制股票图表的方法 def chartStock(ticker): url = "http://finance.yahoo.com/q/hp?s=" + str(ticker) + "+Historical+Prices" sourceCode = requests.get(url) plainText = sourceCode.text soup = BeautifulSoup(plainText, "html.parser") csv = findCSV(soup) parseCSV(csv) # 查找CSV文件的URL def findCSV(soupPage): CSV_URL_PREFIX = 'http://real-chart.finance.yahoo.com/table.csv?s=' links = soupPage.findAll('a') for link in links: href = link.get('href', '') if href.startswith(CSV_URL_PREFIX): return href # 解析CSV文件的每日价格 def parseCSV(csv_text): csv_rows = csv.reader(csv_text.split('\n')) prices = [float(row[4]) for row in csv_rows] days = list(range(len(prices))) point = collections.namedtuple('Point', ['x', 'y']) for price in prices: i = 0 p = point(days[i], prices[i]) points = [] points.append(p) print(points) plotStock(points) # 绘制数据 def plotStock(points): plt.plot(points) plt.show()
CSV文件解析成股票代码数据的问题出现的原因是由于CSV文件中存在一些额外的空行。虽然人们可能认为CSV解析器会跳过这些空行,但实际上并不会。
解决这个问题的方法是在解析CSV文件之前,先检查每一行是否至少有五个元素(即索引位置为4的元素)。可以使用以下代码来实现:
prices = [float(row[4]) for row in csv_rows if len(row) > 4]
另外,还有一个与问题相关的错误是将CSV资源的URL传递给了`parseCSV()`函数,但实际上没有获取到CSV数据。
文章已经整理好了,内容如下:
CSV文件解析成股票代码数据的问题出现的原因是由于CSV文件中存在一些额外的空行。虽然人们可能认为CSV解析器会跳过这些空行,但实际上并不会。解决这个问题的方法是在解析CSV文件之前,先检查每一行是否至少有五个元素(即索引位置为4的元素)。可以使用以下代码来实现:
prices = [float(row[4]) for row in csv_rows if len(row) > 4]
另外,还有一个与问题相关的错误是将CSV资源的URL传递给了`parseCSV()`函数,但实际上没有获取到CSV数据。
问题的原因是parseCSV()
函数期望的是包含CSV数据的字符串,但实际上传递给它的是CSV数据的URL,而不是已下载的CSV数据。这是因为findCSV(soup)
函数返回了页面上找到的CSV链接的href
属性的值,然后将该值传递给parseCSV()
函数。CSV读取器发现只有一行未分隔的数据,所以只有一列,而不是预期的四列以上。
实际上,CSV数据从未被下载。
解决方法是对parseCSV()
函数的前几行进行修改,使其变为以下形式:
def parseCSV(csv_url): r = requests.get(csv_url) csv_rows = csv.reader(r.iter_lines())
...然后,当用户完成这些修改后,他们会发现数据行的外观与此处显示的表格(链接)中的外观相同,所以他们用于解析和绘制数据的其余代码也无法工作。
实际上,根据另一个回答中建议的行长度检查后,我认为用户将什么都看不到-只会得到一个空列表的图。
于是我决定放弃使用CSV模块,自己解析数据。现在运行良好 🙂
所以你现在是在下载CSV数据吗?
哦,我明白了...数据完整吗?底部有分页链接,点击“下一页”可以获取下一页的结果。
确实如此。有时候,我们似乎无法帮到忙 🙂