Skip to content

Instantly share code, notes, and snippets.

@wadefletch
Created June 21, 2019 18:57
Show Gist options
  • Save wadefletch/5586cd005d22a5734e0be01cef1df29f to your computer and use it in GitHub Desktop.
Save wadefletch/5586cd005d22a5734e0be01cef1df29f to your computer and use it in GitHub Desktop.
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