Created
June 21, 2019 18:57
-
-
Save wadefletch/5586cd005d22a5734e0be01cef1df29f to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import json | |
import requests | |
from bs4 import BeautifulSoup | |
class Zacks(object): | |
def __init__(self, username, password): | |
self.username = username | |
self.password = password | |
self.s = self._build_session() | |
# initiates session and establishes necessary cookies | |
self.s.get('https://www.zacks.com') | |
def _build_session(self): | |
headers = requests.utils.default_headers() | |
headers[ | |
'User-Agent'] = 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36' | |
s = requests.Session() | |
s.headers = headers | |
return s | |
def authenticate(self): | |
payload = {'force_login': True, | |
'username': self.username, | |
'password': self.password, | |
'remember_me': 'off'} | |
r = self.s.post('https://www.zacks.com', data=payload) | |
with open('failed_login.html', 'w') as f: | |
f.write(r.text) | |
soup = BeautifulSoup(r.content, 'html.parser') | |
if soup.findAll(text=["* Username or password invalid! Please try again! *", | |
"You have exceeded the number of allowed login attempts"]): | |
return False | |
else: | |
return True | |
@property | |
def portfolio_list(self): | |
r = self.s.get('https://www.zacks.com/portfolios/my-stock-portfolio/') | |
soup = BeautifulSoup(r.content, 'html.parser') | |
portfolio_select = soup.find("select", {"id": "port_id"}) | |
portfolios = [(option.text, option['value']) for option in portfolio_select.findAll('option')] | |
return portfolios | |
def _load_portfolio(self, portfolio_id): | |
self.s.get('https://www.zacks.com/portfolios/my-stock-portfolio/') | |
cookies = { | |
'_sdsat_External Campaign Code': '', | |
'__vrz': '1.16.10', | |
's_fid': '795661B0AD0E4568-3879028CA47BA2B8', | |
's_v17': 'DEF', | |
's_cc': 'true', | |
'_ga': 'GA1.2.1262724362.1561060668', | |
'_gid': 'GA1.2.701511115.1561060668', | |
'_fbp': 'fb.1.1561060668697.1518395262', | |
's_cm': 'Other%20Natural%20Referrersundefinedlocalhost%3A63342', | |
's_cpc': '0', | |
's_p42': '%2Fportfolios%2Fmy-stock-portfolio%2F', | |
'undefined_s': 'First%20Visit', | |
's_nr': '1561141453339-Repeat' | |
} | |
headers = { | |
'x-requested-with': 'XMLHttpRequest', | |
'content-type': 'application/json', | |
} | |
params = { | |
'action': 'retrieve', | |
'portolios_id': portfolio_id, | |
'view_type': 'update' | |
} | |
r = self.s.get('https://www.zacks.com/portfolios/my-stock-portfolio/portfolio_manager.php', params=params, | |
headers=headers) | |
print(r.request.headers) | |
return r | |
def export_portfolio(self, portfolio_id, filename): | |
portfolio_data = self._load_portfolio(portfolio_id) | |
print(portfolio_data.json()) | |
headers = { | |
'content-type': 'application/x-www-form-urlencoded', | |
} | |
payload = { | |
'export_data_init_tab': json.dumps(portfolio_data.json(), separators=(',', ':')), | |
'export_data_rest_tab': '', | |
'XLS_FILE': 'Excelsis' | |
} | |
portfolio_csv = self.s.post('https://www.zacks.com/portfolios/tools/ajxExportExel.php', data=payload, | |
headers=headers) | |
print(str(portfolio_csv.content)) | |
with open(filename, mode='w') as f: | |
f.write(portfolio_csv.text) | |
if __name__ in '__main__': | |
d = Zacks('jake.wallick@outlook.com', 'minijooder') | |
print(d.authenticate()) | |
d.export_portfolio(3069653, d.portfolio_list[1][0] + '.csv') |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment