使用 python yfinance 多线程下载雅虎股票历史

Posted

技术标签:

【中文标题】使用 python yfinance 多线程下载雅虎股票历史【英文标题】:Multithreaded download of yahoo stock history with python yfinance 【发布时间】:2020-06-18 09:20:34 【问题描述】:

我正在尝试下载代码列表的历史数据并将每个数据导出到 csv 文件。我可以使它作为一个 for 循环工作,但是当股票代码列表在 1000 中时,这非常慢。我正在尝试对进程进行多线程处理,但我不断收到许多不同的错误。有时它只会下载 1 个文件,有时会下载 2 或 3 个文件,有时甚至会下载 6 个文件,但永远不会超过。我猜这与拥有 6 核 12 线程处理器有关,但我真的不知道。

import csv
import os
import yfinance as yf
import pandas as pd
from threading import Thread

ticker_list = []

with open('tickers.csv', 'r') as csvfile:
    reader = csv.reader(csvfile, delimiter=',')
    name = None
    for row in reader:
        if row[0]:
            ticker_list.append(row[0])

start_date = '2019-03-03'
end_date = '2020-03-04'

data = pd.DataFrame()

def y_hist(i):
    ticker = ticker_list[i]
    data = yf.download(ticker, start=start_date, end=end_date, group_by="ticker")
    data.to_csv('yhist/' + ticker + '.csv', sep=',', encoding='utf-8')

threads = []

for i in range(os.cpu_count()):
    print('registering thread %d' % i)
    threads.append(Thread(target=y_hist,args=(i,)))

for thread in threads:
    thread.start()

for thread in threads:
    thread.join()

print('done')

这是一个带有代码的 csv 示例文件,足以对此进行测试。 ticker.csv

这些是我阅读并使用的代码以尝试完成这项工作的页面:

multithreading-to-scrape-yahoo-finance

Engineer Man threads

an-introduction-to-asynchronous-programming-in-python

这是一个简化版本,它的输出可能有助于澄清问题。

import os
import pandas as pd
import yfinance as yf
from threading import Thread

ticker_list = ['IBM','MSFT','QQQ','SPY','FB','XLV','XLF','XLK','XLE','GTHX','IYR','ONE','ROG','OLED','GLD']

def y_hist():
    for ticker in ticker_list:
        print(ticker)

threads = []

for i in range(os.cpu_count()):
    threads.append(Thread(target=y_hist))

for thread in threads:
    thread.start()

for thread in threads:
    thread.join()

输出:

IBM
MSFT
QQQ
SPY
FB
XLV
XLF
XLK
XLE
GTHX
IYR
ONE
ROG
OLED
GLD
IBM
MSFT
QQQ
SPY
FB
XLV
XLF
XLK
XLE
GTHX
IYR
ONE
ROG
OLED
GLD
IBM
MSFT
QQQ
SPY
FB
XLV
XLF
XLK
XLE
GTHX
IYR
ONE
ROG
IBM
MSFT
QQQ
SPY
FB
XLV
XLF
XLK
XLE
GTHX
IYR
ONE
ROG
OLED
GLD
OLEDIBM
MSFT
QQQ
SPY
FB
XLV
XLF
XLK
XLE
GTHX
IYR
ONE
GLD
IBM
MSFT
QQQ
SPY
FB
XLV
XLF
XLK
XLE
GTHX
IYR
ONE
ROG
OLED
IBM
GLD
MSFT
ROG
OLED
GLD

QQQ
SPY
FB
XLV
XLF
XLK
XLE
GTHX
IYR
ONE
ROG
OLED
GLD
IBM
MSFT
QQQ
SPY
FB
XLV
XLF
XLK
XLE
GTHX
IYR
ONE
ROG
OLED
GLD
IBM
MSFT
QQQ
SPY
IBM
MSFT
FB
XLV
XLF
XLK
XLE
GTHX
IYR
ONE
ROG
OLED
GLD
QQQ
SPY
FB
XLV
XLF
XLK
XLE
GTHX
IYR
ONE
ROG
OLED
GLD
IBM
MSFT
QQQ
SPY
FB
XLV
XLF
XLK
XLE
GTHX
IYR
ONE
ROG
OLED
IBM
MSFT
QQQ
SPY
FB
XLV
XLF
XLK
XLE
GTHX
IYR
ONE
ROG
OLED
GLD
GLD

【问题讨论】:

【参考方案1】:

虽然这并不能直接修复我损坏的代码,但它是一个可以得到相同结果的解决方案。它使用 yfinance 内置的多线程能力。不幸的是,我仍然不知道为什么原始代码不起作用,并且仍然希望对此提供反馈。同时,如果有人正在寻找同一问题的解决方案,这将起作用。

import csv
import os
import yfinance as yf
import pandas as pd
import time
start = time.time()

ticker_list = []

with open('tickers.csv', 'r') as csvfile:
    reader = csv.reader(csvfile, delimiter=',')
    name = None
    for row in reader:
        if row[0]:
            ticker_list.append(row[0])

data = yf.download(
        tickers = ticker_list,
        period = '1y',
        interval = '1d',
        group_by = 'ticker',
        auto_adjust = False,
        prepost = False,
        threads = True,
        proxy = None
    )

data = data.T

for ticker in ticker_list:
    data.loc[(ticker,),].T.to_csv('yhist/' + ticker + '.csv', sep=',', encoding='utf-8')

print('It took', time.time()-start, 'seconds.')

运行 400 个代码列表的时间:

线程设置为 True

[*********************100%**************************** ] 400 个中的 400 个已完成

耗时 23.420897006988525 秒。

线程设置为 False

[*********************100%**************************** ] 400 个中的 400 个已完成

耗时 133.77732181549072 秒。

【讨论】:

很好的解决方案。但是,在运行上述代码时,我不断收到这个 ``` [WinError 10048] 每个套接字地址(协议/网络地址/端口)通常只允许使用一次')```。知道为什么我会看到这个,我该如何摆脱它? 赞成至少在此处包含您的工作解决方案。

以上是关于使用 python yfinance 多线程下载雅虎股票历史的主要内容,如果未能解决你的问题,请参考以下文章

Python实现多线程HTTP下载器

Python爬虫之多线程下载豆瓣Top250电影图片

使用 python yfinance 多线程下载雅虎股票历史

python多线程下载文件

python多线程下载文件

python多线程爬虫+批量下载斗图啦图片项目(关注持续更新)