Humana Book of Business to CSV Extractor avatar

Humana Book of Business to CSV Extractor

Deprecated
Go to Store
This Actor is deprecated

This Actor is unavailable because the developer has decided to deprecate it. Would you like to try a similar Actor instead?

See alternative Actors
Humana Book of Business to CSV Extractor

Humana Book of Business to CSV Extractor

medicare_tools/humana-book-of-business-to-csv-extractor

.actor/Dockerfile

1# First, specify the base Docker image.
2# You can see the Docker images from Apify at https://hub.docker.com/r/apify/.
3# You can also use any other image from Docker Hub.
4FROM apify/actor-python-selenium:3.11
5
6# Second, copy just requirements.txt into the Actor image,
7# since it should be the only file that affects the dependency install in the next step,
8# in order to speed up the build
9COPY requirements.txt ./
10
11# Install the packages specified in requirements.txt,
12# Print the installed Python version, pip version
13# and all installed packages with their versions for debugging
14RUN echo "Python version:" \
15 && python --version \
16 && echo "Pip version:" \
17 && pip --version \
18 && echo "Installing dependencies:" \
19 && pip install -r requirements.txt \
20 && echo "All installed Python packages:" \
21 && pip freeze
22
23# Next, copy the remaining files and directories with the source code.
24# Since we do this after installing the dependencies, quick build will be really fast
25# for most source file changes.
26COPY . ./
27
28# Use compileall to ensure the runnability of the Actor Python code.
29RUN python3 -m compileall -q .
30
31# Specify how to launch the source code of your Actor.
32# By default, the "python3 -m src" command is run
33CMD ["python3", "-m", "src"]

.actor/actor.json

1{
2    "actorSpecification": 1,
3    "name": "MemberInformation-actor",
4    "title": "Data Extraction for Member Information",
5    "description": "Extracts member information using provided data.",
6    "version": "0.1",
7    "meta": {
8        "templateId": "python-dictionary"
9    },
10    "input": "./input_schema.json",
11    "dockerfile": "./Dockerfile",
12    "storages": {
13        "dataset": {
14            "actorSpecification": 1,
15            "title": "Member Information Data",
16            "views": {
17                "member": {
18                    "title": "Member Information Data",
19                    "transformation": {
20                        "fields": [
21                            "First Name",
22                            "Last Name",
23                            "MBI",
24                            "DOB",
25                            "Medicaid #",
26                            "LIS",
27                            "Carrier",
28                            "Carrier Member #",
29                            "Status",
30                            "Plan Type",
31                            "Contract #",
32                            "Plan Name",
33                            "Monthly premium",
34                            "PCP on file",
35                            "Phone",
36                            "Email",
37                            "Address Line 1",
38                            "Address Line 2",
39                            "City",
40                            "State",
41                            "Zip",
42                            "County",
43                            "Application ID",
44                            "Election Code",
45                            "Application Date",
46                            "Approval Date",
47                            "Effective Date",
48                            "Termination Date",
49                            "Termination Reason",
50                            "Writing Agent",
51                            "Writing Agent NPN",
52                            "Agent Writing ID"
53                        ]
54                    },
55                    "display": {
56                        "component": "table",
57                        "properties": {
58                            "First Name": {
59                                "label": "First Name",
60                                "format": "text"
61                            },
62                            "Last Name": {
63                                "label": "Last Name",
64                                "format": "text"
65                            },
66                            "MBI": {
67                                "label": "MBI",
68                                "format": "text"
69                            },
70                            "DOB": {
71                                "label": "Date of Birth",
72                                "format": "text"
73                            },
74                            "Medicaid #": {
75                                "label": "Medicaid Number",
76                                "format": "text"
77                            },
78                            "LIS": {
79                                "label": "LIS Indicator",
80                                "format": "text"
81                            },
82                            "Carrier": {
83                                "label": "Carrier",
84                                "format": "text"
85                            },
86                            "Carrier Member #": {
87                                "label": "Carrier Member Number",
88                                "format": "text"
89                            },
90                            "Status": {
91                                "label": "Status",
92                                "format": "text"
93                            },
94                            "Plan Type": {
95                                "label": "Plan Type",
96                                "format": "text"
97                            },
98                            "Contract #": {
99                                "label": "Contract Number",
100                                "format": "text"
101                            },
102                            "Plan Name": {
103                                "label": "Plan Name",
104                                "format": "text"
105                            },
106                            "Monthly premium": {
107                                "label": "Monthly Premium",
108                                "format": "text"
109                            },
110                            "PCP on file": {
111                                "label": "Primary Care Physician on File",
112                                "format": "text"
113                            },
114                            "Phone": {
115                                "label": "Phone",
116                                "format": "text"
117                            },
118                            "Email": {
119                                "label": "Email",
120                                "format": "text"
121                            },
122                            "Address Line 1": {
123                                "label": "Address Line 1",
124                                "format": "text"
125                            },
126                            "Address Line 2": {
127                                "label": "Address Line 2",
128                                "format": "text"
129                            },
130                            "City": {
131                                "label": "City",
132                                "format": "text"
133                            },
134                            "State": {
135                                "label": "State",
136                                "format": "text"
137                            },
138                            "Zip": {
139                                "label": "Zip",
140                                "format": "text"
141                            },
142                            "County": {
143                                "label": "County",
144                                "format": "text"
145                            },
146                            "Application ID": {
147                                "label": "Application ID",
148                                "format": "text"
149                            },
150                            "Election Code": {
151                                "label": "Election Code",
152                                "format": "text"
153                            },
154                            "Application Date": {
155                                "label": "Application Date",
156                                "format": "text"
157                            },
158                            "Approval Date": {
159                                "label": "Approval Date",
160                                "format": "text"
161                            },
162                            "Effective Date": {
163                                "label": "Effective Date",
164                                "format": "text"
165                            },
166                            "Termination Date": {
167                                "label": "Termination Date",
168                                "format": "text"
169                            },
170                            "Termination Reason": {
171                                "label": "Termination Reason",
172                                "format": "text"
173                            },
174                            "Writing Agent": {
175                                "label": "Writing Agent",
176                                "format": "text"
177                            },
178                            "Writing Agent NPN": {
179                                "label": "Writing Agent NPN",
180                                "format": "text"
181                            },
182                            "Agent Writing ID": {
183                                "label": "Agent Writing ID",
184                                "format": "text"
185                            }
186                        }
187                    }
188                }
189            }
190        }
191    }
192}

.actor/input_schema.json

1{
2  "title": "HumanaScraper",
3  "type": "object",
4  "schemaVersion": 1,
5  "properties": {
6    "username": {
7      "title": "Username/Email",
8      "type": "string",
9      "description": "Enter the username or email address used for login.",
10      "editor": "textfield"
11    },
12    "password": {
13      "title": "Password",
14      "type": "string",
15      "description": "Enter the password for login.",
16      "isSecret": true,
17      "editor": "textfield"
18    }
19},
20  "required": ["username", "password"]
21}

src/__main__.py

1"""
2This module serves as the entry point for executing the Apify Actor. It handles the configuration of logging
3settings. The `main()` coroutine is then executed using `asyncio.run()`.
4
5Feel free to modify this file to suit your specific needs.
6"""
7
8import asyncio
9import logging
10
11from apify.log import ActorLogFormatter
12
13from .main import main
14
15# Configure loggers
16handler = logging.StreamHandler()
17handler.setFormatter(ActorLogFormatter())
18
19apify_client_logger = logging.getLogger('apify_client')
20apify_client_logger.setLevel(logging.INFO)
21apify_client_logger.addHandler(handler)
22
23apify_logger = logging.getLogger('apify')
24apify_logger.setLevel(logging.DEBUG)
25apify_logger.addHandler(handler)
26
27# Execute the Actor main coroutine
28asyncio.run(main())

src/main.py

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    # send npi
27    browser.find_element(By.CSS_SELECTOR, 'input[name="Username"]').send_keys(username)
28    # send password
29    browser.find_element(By.CSS_SELECTOR, 'input[name="Password"]').send_keys(password)
30    # click login
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    # browse.refresh()
44    # click p with View All Customers text
45    browser.find_element(By.XPATH, '//p[text()="View All Customers"]').click()
46    # browser.get("https://agentportal.humana.com/Vantage/apps/index.html?agenthome=-1#!/businessCenter")
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    # print(response.text)
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        # Read the Actor input
165        actor_input = await Actor.get_input() or {}
166        username = actor_input.get("username")
167        password = actor_input.get("password")
168        # check both start_date and end_date are not empty
169        # Launch a new Selenium Chrome WebDriver
170        Actor.log.info('Launching Chrome WebDriver...')
171        # chrome_options = ChromeOptions()
172        # if Actor.config.headless:
173        #     chrome_options.add_argument('--headless')
174        # chrome_options.add_argument('--no-sandbox')
175        # chrome_options.add_argument('--disable-dev-shm-usage')
176        # chrome_options.add_argument('--window-size=1920,1080')
177        # browser = webdriver.Chrome(options=chrome_options)
178        browser = Driver(uc=True, headless=True)
179        # ruh the login function
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())

.dockerignore

1# configurations
2.idea
3
4# crawlee and apify storage folders
5apify_storage
6crawlee_storage
7storage
8
9# installed files
10.venv
11
12# git folder
13.git

.editorconfig

1root = true
2
3[*]
4indent_style = space
5indent_size = 4
6charset = utf-8
7trim_trailing_whitespace = true
8insert_final_newline = true
9end_of_line = lf

.gitignore

1# This file tells Git which files shouldn't be added to source control
2
3.idea
4.DS_Store
5
6apify_storage
7storage
8
9.venv/
10.env/
11__pypackages__
12dist/
13build/
14*.egg-info/
15*.egg
16
17__pycache__
18
19.mypy_cache
20.dmypy.json
21dmypy.json
22.pytest_cache
23.ruff_cache
24
25.scrapy
26*.log

requirements.txt

1# Add your dependencies here.
2# See https://pip.pypa.io/en/latest/reference/requirements-file-format/
3# for how to format them
4apify ~= 1.2.0
5selenium ~= 4.14.0
6seleniumbase
7tqdm
8bs4
9pandas
Developer
Maintained by Community