Skip to content

Commit 18fed91

Browse files
committed
Moved methods into separate files
1 parent e879c1b commit 18fed91

File tree

6 files changed

+93
-62
lines changed

6 files changed

+93
-62
lines changed

.idea/dataSources.xml

+23
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/sqldialects.xml

+6
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

finviz/__init__.py

Whitespace-only changes.

finviz/async_connector.py renamed to finviz/request_functions.py

+15
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,20 @@
11
import asyncio
22
import aiohttp
3+
import requests
4+
import urllib3
5+
6+
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
7+
8+
9+
def http_request(url, payload=None):
10+
11+
if payload is None:
12+
payload = {}
13+
14+
content = requests.get(url, params=payload, verify=False)
15+
content.raise_for_status() # Raise HTTPError for bad requests (4xx or 5xx)
16+
17+
return content, content.url
318

419

520
class Connector(object):

finviz/scraper_functions.py

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
from lxml import etree
2+
3+
4+
def get_total_rows(page_content):
5+
total_element = page_content.cssselect('td[width="140"]')
6+
7+
return int(etree.tostring(total_element[0]).decode("utf-8").split('</b>')[1].split(' ')[0])
8+
9+
10+
def get_page_urls(page_content, rows, url):
11+
12+
try:
13+
total_pages = int([i.text.split('/')[1] for i in page_content.cssselect('option[value="1"]')][0])
14+
except IndexError:
15+
raise Exception("No results matching the criteria: {}"
16+
.format(url.split('?', 1)[1]))
17+
18+
urls = []
19+
20+
for page_number in range(1, total_pages + 1):
21+
22+
sequence = 1 + (page_number - 1) * 20
23+
24+
if sequence - 20 <= rows < sequence:
25+
break
26+
else:
27+
urls.append(url + '&r={}'.format(str(sequence)))
28+
29+
return urls

finviz/screener.py

+20-62
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,7 @@
1-
from finviz.async_connector import Connector
21
from lxml import html
32
from lxml import etree
4-
import requests
5-
import urllib3
6-
import os
7-
8-
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
9-
10-
TABLE = {
11-
'Overview': '110',
12-
'Valuation': '120',
13-
'Ownership': '130',
14-
'Performance': '140',
15-
'Custom': '150',
16-
'Financial': '160',
17-
'Technical': '170'
18-
}
19-
20-
21-
def http_request(url, payload=None):
22-
23-
if payload is None:
24-
payload = {}
25-
26-
content = requests.get(url, params=payload, verify=False)
27-
content.raise_for_status() # Raise HTTPError for bad requests (4xx or 5xx)
28-
29-
return content, content.url
3+
import finviz.request_functions as send
4+
import finviz.scraper_functions as scrape
305

316

327
class Screener(object):
@@ -57,38 +32,15 @@ def __init__(self, tickers=None, filters=None, rows=None, order='', signal='', t
5732

5833
def to_csv(self, directory=None):
5934

60-
from save_data import export_to_csv
35+
from .save_data import export_to_csv
6136

6237
if directory is None:
38+
39+
import os
6340
directory = os.getcwd()
6441

6542
export_to_csv(self.headers, self.data, directory)
6643

67-
def __get_total_rows(self):
68-
69-
total_element = self.page_content.cssselect('td[width="140"]')
70-
self.rows = int(etree.tostring(total_element[0]).decode("utf-8").split('</b>')[1].split(' ')[0])
71-
72-
def __get_page_urls(self):
73-
74-
try:
75-
total_pages = int([i.text.split('/')[1] for i in self.page_content.cssselect('option[value="1"]')][0])
76-
except IndexError: # No results found
77-
return None
78-
79-
urls = []
80-
81-
for page_number in range(1, total_pages + 1):
82-
83-
sequence = 1 + (page_number - 1) * 20
84-
85-
if sequence - 20 <= self.rows < sequence:
86-
break
87-
else:
88-
urls.append(self.url + '&r={}'.format(str(sequence)))
89-
90-
self.page_urls = urls
91-
9244
def __get_table_headers(self):
9345

9446
first_row = self.page_content.cssselect('tr[valign="middle"]')
@@ -137,27 +89,33 @@ def parse_row(line):
13789

13890
def __search_screener(self):
13991

92+
table = {
93+
'Overview': '110',
94+
'Valuation': '120',
95+
'Ownership': '130',
96+
'Performance': '140',
97+
'Custom': '150',
98+
'Financial': '160',
99+
'Technical': '170'
100+
}
101+
140102
payload = {
141-
'v': TABLE[self.table],
103+
'v': table[self.table],
142104
't': ','.join(self.tickers),
143105
'f': ','.join(self.filters),
144106
'o': self.order,
145107
's': self.signal
146108
}
147109

148-
self.page_content, self.url = http_request('https://finviz.com/screener.ashx', payload)
110+
self.page_content, self.url = send.http_request('https://finviz.com/screener.ashx', payload)
149111
self.page_content = html.fromstring(self.page_content.text) # Parses the page with the default lxml parser
150112

151113
self.__get_table_headers()
152114

153115
if self.rows is None:
154-
self.__get_total_rows()
155-
156-
self.__get_page_urls()
116+
self.rows = scrape.get_total_rows(self.page_content)
157117

158-
if self.page_urls is None:
159-
raise Exception("No results matching the criteria: {}"
160-
.format(self.url.split('?', 1)[1]))
118+
self.page_urls = scrape.get_page_urls(self.page_content, self.rows, self.url)
161119

162-
async_connector = Connector(self.__get_table_data, self.page_urls)
120+
async_connector = send.Connector(self.__get_table_data, self.page_urls)
163121
self.data = async_connector.run_connector()

0 commit comments

Comments
 (0)