issue with \screener.py
Opened this issue · 5 comments
I have been trying to just pull a stock list of all stocks on Finviz.com and my script was working just fine.
Then all of a sudden it stopped with this error.
finviz\screener.py", line 128, in init
self.data = self.__search_screener()
Research says it is something to do with starting with 0 versus a 1, but i cannot find it in the code.
here is the script i am running.
`from finviz.screener import Screener
import datetime
stock_list = Screener()
print(type(stock_list))
stock_list.to_csv('finviz_stocks_list'+(datetime.datetime.now().date().strftime('%m-%d-%Y')+'.csv'))
`
this was fixed in the current Master release. Thank you. I downloaded it and manually replaced the scripts. works well. Thank you
I have opened a pull request with a fix as this issue continues.
I am also seeing the IndexError on initialization. How do I pip install the pull request with the fix?
Thank you, please keep me posted
`~\anaconda3\lib\site-packages\finviz\screener.py in init(self, tickers, filters, rows, order, signal, table, custom, user_agent, request_method)
126
127 self.analysis = []
--> 128 self.data = self.__search_screener()
129
130 def call(
~\anaconda3\lib\site-packages\finviz\screener.py in __search_screener(self)
434 )
435
--> 436 self._rows = self.__check_rows()
437 self.headers = self.__get_table_headers()
438
~\anaconda3\lib\site-packages\finviz\screener.py in __check_rows(self)
405
406 if self._total_rows == 0:
--> 407 raise NoResults(self._url.split("?")[1])
408 elif self._rows is None or self._rows > self._total_rows:
409 return self._total_rows
NoResults: No results found for query: v=141&t=&f=exch_nasd%2Cidx_sp500&o=price&s=&c=`
The core issue appears to be that the scrape module in screener.py is no longer functioning properly. In the check_rows function, total_rows is set to scrape.get_total_rows. which is returning no result. The issue appears to be in the scraper_functions.py module.
I suspect, but have not investigated deeply enough yet that the get_table function in scraper_functions.py is malfunctioning due to a new html structure at Finviz.
Here is the current code of that function:
`
def get_table(page_html: requests.Response, headers, rows=None, **kwargs):
""" Private function used to return table data inside a list of dictionaries. """
if isinstance(page_html, str):
page_parsed = html.fromstring(page_html)
else:
page_parsed = html.fromstring(page_html.text)
# When we call this method from Portfolio we don't fill the rows argument.
# Conversely, we always fill the rows argument when we call this method from Screener.
# Also, in the portfolio page, we don't need the last row - it's redundant.
if rows is None:
rows = -2 # We'll increment it later (-1) and use it to cut the last row
data_sets = []
# Select the HTML of the rows and append each column text to a list
all_rows = [
column.xpath("td//text()")
for column in page_parsed.cssselect('tr[valign="top"]')
]
# If rows is different from -2, this function is called from Screener
if rows != -2:
for row_number, row_data in enumerate(all_rows, 1):
data_sets.append(dict(zip(headers, row_data)))
if row_number == rows: # If we have reached the required end
break
else:
# Zip each row values to the headers and append them to data_sets
[data_sets.append(dict(zip(headers, row))) for row in all_rows]
return data_sets
`
I am guessing all_rows is likely where the problem resides.