"TypeError: string indices must be integers" when getting data of a stock from Yahoo Finance using Pandas Datareader
Asked Answered
L

5

49
import pandas_datareader

end = "2022-12-15"
start = "2022-12-15"
stock_list = ["TATAELXSI.NS"]

data = pandas_datareader.get_data_yahoo(symbols=stock_list, start=start, end=end)

print(data)

When I run this code, I get error "TypeError: string indices must be integers".

Edit : I have updated the code and passed list as symbol parameter but it still shows the same error

Error :

Traceback (most recent call last):
  File "C:\Users\Deepak Shetter\PycharmProjects\100DAYSOFPYTHON\mp3downloader.py", line 7, in <module>
    data = pandas_datareader.get_data_yahoo(symbols=[TATAELXSI], start=start, end=end)
  File "C:\Users\Deepak Shetter\PycharmProjects\100DAYSOFPYTHON\venv\lib\site-packages\pandas_datareader\data.py", line 80, in get_data_yahoo
    return YahooDailyReader(*args, **kwargs).read()
  File "C:\Users\Deepak Shetter\PycharmProjects\100DAYSOFPYTHON\venv\lib\site-packages\pandas_datareader\base.py", line 258, in read
    df = self._dl_mult_symbols(self.symbols)
  File "C:\Users\Deepak Shetter\PycharmProjects\100DAYSOFPYTHON\venv\lib\site-packages\pandas_datareader\base.py", line 268, in _dl_mult_symbols
    stocks[sym] = self._read_one_data(self.url, self._get_params(sym))
  File "C:\Users\Deepak Shetter\PycharmProjects\100DAYSOFPYTHON\venv\lib\site-packages\pandas_datareader\yahoo\daily.py", line 153, in _read_one_data
    data = j["context"]["dispatcher"]["stores"]["HistoricalPriceStore"]
TypeError: string indices must be integers
Latium answered 17/12, 2022 at 6:53 Comment(5)
has it only been recent? was it happening even before?Caroncarotene
I would suggest to use yfinance in the meanwhile..Caroncarotene
@NikhilMulley It happened just today(Saturday , dec 16). Was working fine yesterday.Latium
It started happening to me today too. No changes to the code that yesterday was working fine.Archway
I am discovering it just now, but indeed, failing for me too.Opus
A
20

None of the solutions reported here so far worked for me. As per the discussion here Yahoo made changes to their API that broke compatibility with previous pandas datareader versions.

In the same Github thread a fix is reported, implemented in a pull request from Github user raphi6. I confirmed the pull request works fine. The version from the pull request can be installed with this 3 lines:

conda install pycryptodome pycryptodomex
conda uninstall pandas-datareader
pip install git+https://github.com/raphi6/pandas-datareader.git@ea66d6b981554f9d0262038aef2106dda7138316

The pycrypto* packages are dependencies I have to install to make it work. Notice I am using the commit hash here instead of the branch name, because it is Yahoo!_Issue#952 and there is an issue with hash characters when using pip this way.

This can also be done using pip for all the commands instead of conda (see Update 1 below).

Update 1

To try this on Google Colab use (as shown here):

! pip install pycryptodome pycryptodomex
! pip uninstall --yes pandas-datareader
! pip install git+https://github.com/raphi6/pandas-datareader.git@ea66d6b981554f9d0262038aef2106dda7138316

Update 2 (27/12/2022)

Although past week I could not make it work, I have tried again, and I can confirm that the pdr_override() workaround mentioned below by Nikhil Mulley is working now (at least with yfinance 0.2.3 and pandas-datareader 0.10.0).

Original answer (works but more lines of code)

In the same Github thread a fix is reported, implemented in a pull request from Github user raphi6. I confirmed the pull request works fine. Detailed installation instructions for the pull request can be found here, copied below for the sake of completeness:

git clone https://github.com/raphi6/pandas-datareader.git
cd pandas-datareader
conda uninstall pandas-datareader
conda install pycryptodome pycryptodomex
git checkout 'Yahoo!_Issue#952'
python setup.py install --record installed_files.txt

The --record argument in the install command is to get a list of installed files, so that it is easy to uninstall in the future (following this SO thread). The pycrypto* files are dependencies I have to install to make it work.

Archway answered 19/12, 2022 at 17:16 Comment(5)
Is it possible to implement this in google colab?Implacable
Not sure about this working in google colab. I've tried installing it using this ! git clone https://github.com/raphi6/pandas-datareader.git && cd pandas-datareader && git checkout 'Yahoo!_Issue#952' && pip uninstall --yes pandas-datareader && yes | pip install pycryptodome pycryptodomex && python setup.py install --record installed_files.txt. Command seems to work fine in google colab, but then import pandas_datareader failed with a module not found error. Any clue?Archway
The updated issue in Github shows how to do it in Google Colab. I've updated my answer accordingly.Archway
Updated answer with a more elegant solution using pip instead of setup.py, also friendlier with Google Colab.Archway
I've executed the Update 2 shell commands, but am getting a different error Padding is incorrect. Seems strange that in 2024 we would be getting the same error listed above.Obau
P
20

My solution is simple, I just replace the pandas_datareader.get_data_yahoo with yf.download. And needless to worry about the result, because yf.download will also give you a dataframe. I simplify my syntax as below:

import yfinance as yf

df = yf.download(your_ticks_or_a_tick_list, start=start_date, end=end_date)

But please remember to Clear Outputs of All Cells, and Restart or you will get an error.

Palmate answered 31/1, 2023 at 12:58 Comment(2)
Thanks, this worked for me as of Jul/2023Bohn
Superior answerSnowblind
C
14

This is not an answer, but I think the problem is related with pdr data reader fetching from yahoo itself

>>> import pandas_datareader as dtr
>>> from datetime import datetime
>>> initial_portfolio=['AAPL', 'MA', 'F', 'MSFT', '^GSPC']
>>> startdate = datetime(2022,12,1)
>>> enddate=datetime(2022,12,10)
>>> stock_data=dtr.yahoo.daily.YahooDailyReader(initial_portfolio,start=startdate,end=enddate).read()

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "lib/python3.9/site-packages/pandas_datareader/base.py", line 258, in read
    df = self._dl_mult_symbols(self.symbols)
  File "lib/python3.9/site-packages/pandas_datareader/base.py", line 268, in _dl_mult_symbols
    stocks[sym] = self._read_one_data(self.url, self._get_params(sym))
  File "lib/python3.9/site-packages/pandas_datareader/yahoo/daily.py", line 153, in _read_one_data
    data = j["context"]["dispatcher"]["stores"]["HistoricalPriceStore"]
TypeError: string indices must be integers

and the short term fix could be to use yfinance override and see if that helps in the meanwhile until yahoo finance restores their data functionality?

Python 3.9.1 (default, Dec 28 2020, 11:22:14)
[Clang 11.0.0 (clang-1100.0.33.17)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from pandas_datareader import data as pdr
>>> import yfinance as yf
>>> yf.pdr_override()
>>> y_symbols = ['SCHAND.NS', 'TATAPOWER.NS', 'ITC.NS']
>>> from datetime import datetime
>>> startdate = datetime(2022,12,1)
>>> enddate = datetime(2022,12,15)
>>> data = pdr.get_data_yahoo(y_symbols, start=startdate, end=enddate)
[*********************100%***********************]  3 of 3 completed
>>> data
             Adj Close                                Close                           ...        Open                             Volume
                ITC.NS   SCHAND.NS TATAPOWER.NS      ITC.NS   SCHAND.NS TATAPOWER.NS  ...      ITC.NS   SCHAND.NS TATAPOWER.NS    ITC.NS SCHAND.NS TATAPOWER.NS
Date                                                                                  ...
2022-12-01  339.549988  195.949997   224.850006  339.549988  195.949997   224.850006  ...  341.700012  191.600006   225.250000  16630417    544485      7833074
2022-12-02  337.149994  196.600006   225.250000  337.149994  196.600006   225.250000  ...  339.350006  196.000000   225.449997   8388835    122126      7223274
2022-12-05  336.750000  191.050003   224.199997  336.750000  191.050003   224.199997  ...  337.649994  200.850006   225.250000   9716390    107294     10750610
2022-12-06  337.299988  196.399994   228.800003  337.299988  196.399994   228.800003  ...  334.100006  191.000000   224.199997   6327430    102911     20071039
2022-12-07  340.100006  187.350006   225.850006  340.100006  187.350006   225.850006  ...  338.500000  198.000000   228.800003   9813208    122772      7548312
2022-12-08  338.399994  181.850006   225.050003  338.399994  181.850006   225.050003  ...  340.200012  186.000000   226.000000   6200447    114147      7507975
2022-12-09  341.399994  176.899994   219.399994  341.399994  176.899994   219.399994  ...  339.750000  183.899994   225.899994   8132228    179660     13087278
2022-12-12  343.200012  177.350006   217.699997  343.200012  177.350006   217.699997  ...  341.000000  177.750000   219.750000  11214662    133507      8858525
2022-12-13  345.600006  178.449997   218.850006  345.600006  178.449997   218.850006  ...  344.500000  179.350006   218.800003  10693426     74873      7265105
2022-12-14  345.399994  179.149994   222.699997  345.399994  179.149994   222.699997  ...  346.000000  180.449997   219.800003   7379878     32085      9179593

[10 rows x 18 columns]
>>>
Caroncarotene answered 17/12, 2022 at 9:20 Comment(0)
D
11

Use yahoo finance instead, it worked for me:

import datetime as dt
import yfinance as yf

company = 'TATAELXSI.NS'

# Define a start date and End Date
start = dt.datetime(2020,1,1)
end =  dt.datetime(2022,1,1)

# Read Stock Price Data 
data = yf.download(company, start , end)

data.tail(10)
Dynast answered 8/1, 2023 at 16:4 Comment(0)
H
2

the solution that worked for me in 09/25/2023

i replace

import pandas_datareader as web
web.DataReader('AMZN', 'yahoo', start, end)

with

import yfinance 
yfinance.download('AMZN', start, end)
Hollister answered 25/9, 2023 at 22:16 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.