1from urllib.parse import urljoin
2from selenium import webdriver
3from selenium.webdriver.chrome.options import Options as ChromeOptions
4from selenium.webdriver.common.by import By
5from apify import Actor
6import asyncio
7import time
8import random
9from selenium.webdriver.support.ui import Select
10from selenium.webdriver.common.keys import Keys
11from selenium.webdriver.common.by import By
12import requests
13from bs4 import BeautifulSoup as bs
14import csv
15import pandas as pd
16from tqdm import tqdm
17from datetime import datetime, timedelta
18import dateutil.relativedelta
19from seleniumbase import Driver
20from concurrent.futures import ThreadPoolExecutor
21
22
23async def login(browser, username, password):
24 browser.get('https://account.humana.com/')
25 time.sleep(random.uniform(4, 5))
26
27 browser.find_element(By.CSS_SELECTOR, 'input[name="Username"]').send_keys(username)
28
29 browser.find_element(By.CSS_SELECTOR, 'input[name="Password"]').send_keys(password)
30
31 browser.find_element(By.CSS_SELECTOR, 'button[type="submit"]').click()
32 time.sleep(random.uniform(15, 20))
33 try:
34 browser.find_element(By.XPATH, '//*[@id="multiPortalAccessForm"]/ul/li[2]/button').click()
35 time.sleep(random.uniform(10,15))
36 except:
37 pass
38 try:
39 browser.find_element(By.XPATH, '//a[contains(text(),"Vantage")]').click()
40 time.sleep(2)
41 except:
42 pass
43
44
45 browser.find_element(By.XPATH, '//p[text()="View All Customers"]').click()
46
47 time.sleep(random.uniform(20,30))
48 cookies = browser.get_cookies()
49 cookies = {cookie['name']: cookie['value'] for cookie in cookies}
50 return cookies
51
52
53async def get_list(cookies, headers):
54 json_data = {
55 'filters': {
56 'dateFilter': None,
57 'filterValuesIds': [],
58 },
59 'insightId': 'all',
60 'resultPaging': {
61 'amount': 50,
62 'page': 0,
63 },
64 'resultSort': {
65 'columnId': 49,
66 'order': 'asc',
67 },
68 }
69
70 response = requests.post(
71 'https://agentportal.humana.com/Vantage/api/businesscenter/search-policies-and-applications',
72 cookies=cookies,
73 headers=headers,
74 json=json_data,
75 )
76
77 data = response.json()
78 total = data['totalRecords']
79 total_pages = total//50+1
80 list_data = data['records']
81 for i in range(1, total_pages):
82 json_data['resultPaging']['page'] = i
83 response = requests.post(
84 'https://agentportal.humana.com/Vantage/api/businesscenter/search-policies-and-applications',
85 cookies=cookies,
86 headers=headers,
87 json=json_data,
88 )
89 data = response.json()
90 list_data += data['records']
91 return list_data
92
93
94async def process(full_data):
95 memberInformation = full_data['memberInformation']
96 otherPolicyInformation = full_data['otherPolicyInformation']
97 policyInformation = full_data['policyInformation']
98 compensatedAgentInfo = full_data['compensatedAgentInfo']
99 memberInformation_dict = {
100 "First Name": memberInformation['mbrFirstName'],
101 "Last Name": memberInformation['mbrLastName'] + memberInformation['mbrMiddleInit'],
102 "MBI": memberInformation['medicareId'],
103 "DOB": datetime.strptime(memberInformation['birthDate'], "%Y-%m-%dT%H:%M:%SZ").strftime("%d/%m/%Y") if memberInformation['birthDate'] is not None else None,
104 "Medicaid #": memberInformation['medicaidId'],
105 "LIS": memberInformation['lisIndicator'],
106 "Carrier":"Humana",
107 "Carrier Member #":otherPolicyInformation[0]['humanaID'],
108 "Status": otherPolicyInformation[0]['status'],
109 "Plan Type": otherPolicyInformation[0]['planType'],
110 "Contract #": otherPolicyInformation[0]['product'],
111 "Plan Name": otherPolicyInformation[0]['planAltDesc'],
112 "Monthly premium":"-",
113 "PCP on file": policyInformation['mbrName'],
114 "Phone": memberInformation['mbrPrimPhone'],
115 "Email": memberInformation['mbrEmail'],
116 "Address Line 1": memberInformation['address']['residentAddressLine1'],
117 "Address Line 1": memberInformation['address']['residentAddressLine2'],
118 "City": memberInformation['address']['residentCityName'],
119 "State": memberInformation['address']['residentStateCode'],
120 "Zip": memberInformation['address']['residentZipCode'],
121 "County": memberInformation['address']['residentCountyName'],
122 "Application ID": policyInformation['applicationId'],
123 "Election Code": policyInformation['electionTypeCode'],
124 "Application Date": datetime.strptime(policyInformation['signatureDate'], "%Y-%m-%dT%H:%M:%SZ").strftime("%d/%m/%Y") if memberInformation['birthDate'] is not None else None,
125 "Approval Date": "-",
126 "Effective Date": datetime.strptime(policyInformation['covEffDate'],"%Y-%m-%dT%H:%M:%SZ").strftime("%d/%m/%Y") if memberInformation['birthDate'] is not None else None,
127 "Termination Reason":"-",
128 "Writing Agent": otherPolicyInformation[0]['writingAgent'],
129 "Writing Agent NPN": otherPolicyInformation[0]['npn'],
130
131 }
132
133 try:
134 memberInformation_dict["Termination Date"] = datetime.strptime(policyInformation['covTermDate'],"%Y-%m-%dT%H:%M:%SZ").strftime("%d/%m/%Y")
135 except:
136 memberInformation_dict["Termination Date"] = ''
137
138 try:
139 memberInformation_dict["Agent Writing ID"] = compensatedAgentInfo['aorSan']
140 except:
141 memberInformation_dict["Agent Writing ID"] = ''
142 return memberInformation_dict
143
144
145async def get_details(cookies, headers, d):
146 today = datetime.today()
147 month = today.month
148 year = today.year
149 day = today.day
150 url = f"https://agentportal.humana.com/Vantage/api/businesscenter/member?recordId={d['id']}&salesMemKey={d['salesMemKey']}&modifiedDTime={year}%2F{month}%2F{day}T00:00:00Z"
151 response = requests.get(
152 url,
153 cookies=cookies,
154 headers=headers,
155 )
156 full_data = response.json()
157 memberInformation_dict = await process(full_data)
158 print(f"Got Data for {d['id']}")
159 await Actor.push_data(memberInformation_dict)
160 return memberInformation_dict
161
162async def main():
163 async with Actor:
164
165 actor_input = await Actor.get_input() or {}
166 username = actor_input.get("username")
167 password = actor_input.get("password")
168
169
170 Actor.log.info('Launching Chrome WebDriver...')
171
172
173
174
175
176
177
178 browser = Driver(uc=True, headless=True)
179
180 cookies = await login(browser, username, password)
181 Actor.log.info("Logged In!")
182 headers = {
183 'Accept': 'application/json, text/plain, */*',
184 'Accept-Language': 'en-GB,en-US;q=0.9,en;q=0.8',
185 'Authorization': 'Basic VmFudGFnZVdlYkFwcDpwN1JFdmVkIzE=',
186 'Connection': 'keep-alive',
187 'Content-Type': 'application/json',
188 'Origin': 'https://agentportal.humana.com',
189 'Referer': 'https://agentportal.humana.com/Vantage/apps/index.html?agenthome=-1',
190 'Sec-Fetch-Dest': 'empty',
191 'Sec-Fetch-Mode': 'cors',
192 'Sec-Fetch-Site': 'same-origin',
193 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
194 'sec-ch-ua': '"Not_A Brand";v="8", "Chromium";v="120", "Google Chrome";v="120"',
195 'sec-ch-ua-mobile': '?0',
196 'sec-ch-ua-platform': '"Windows"',
197 }
198 headers['x-dtpc'] = cookies['dtPC']
199 list_data = await get_list(cookies, headers)
200 Actor.log.info("Getting Data....")
201 csv_df = []
202 with ThreadPoolExecutor(max_workers=5) as executor:
203 tasks = [get_details(cookies, headers, d) for d in tqdm(list_data)]
204 await asyncio.gather(*tasks)
205 Actor.log.info("Completed.")
206 browser.quit()
207if __name__ == "__main__":
208 asyncio.run(main())