I am new to python, but need to modify code created by someone else. I am not able to post the full code, but I posted most of it below:
from bs4 import BeautifulSoup
import datetime
import getpass
from gmail import Gmail
from selenium import webdriver
from selenium.common.exceptions import NoSuchElementException
from selenium.common.exceptions import ElementNotVisibleException
from time import sleep
from selenium.common.exceptions import NoAlertPresentException
from selenium.webdriver.support import expected_conditions as EC
def soupify(session, url):
"""
Makes parse-able HTML from any given URL.
:param session: requests.Session()
:param url: str
:return: BeautifulSoup object
"""
while True:
try:
r = session.get(url)
break
except Exception as e:
print(e)
return BeautifulSoup(r.content, 'html.parser')
def create_http_session():
"""
Quick little function for returning a requests.Session() instance
with a properly set User-Agent header.
:return: requests.Session()
"""
session = requests.Session()
session.headers.update({'User-Agent':
'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36'
})
return session
def retrieve_hidden_input(soup, name):
return soup.find('input', attrs={
'type': 'hidden',
'name': name
}).get('value')
class AmericanHomesScraper:
def __init__(self, username, password, testing):
self.username = username
self.password = password
self.testing = testing
self.chrome_session = webdriver.PhantomJS()
self.chrome_session.maximize_window()
self.g = Gmail()
self.g.login(username, password)
self.index = 0
def check_for_new_emails_from_sender(self,
sender='[email protected]'):
self.index += 1
if self.index % 1000 == 0:
print('Checking emails - {0}.'.format(datetime.datetime.now()))
elif self.index == 1:
print('Checking emails - {0}.'.format(datetime.datetime.now()))
else:
pass
for s in sender:
messages = self.g.inbox().mail(sender=s,
unread=True)
for message in messages:
message.read()
print(
'Email from {0}: {1}.'.format(s, datetime.datetime.now()))
self.check_for_listings()
self.g.logout()
self.g = Gmail()
self.g.login(self.username, self.password)
def login(self, username, ahsPassword):
self.ahsPassword = ahsPassword
self.chrome_session.get('https://www.aaa.com/Login.aspx')
self.chrome_session.find_element_by_xpath(
'//*[@id="txtUsername"]'
).send_keys(username)
self.chrome_session.find_element_by_xpath(
'//*[@id="txtPassword"]'
).send_keys(ahsPassword)
self.chrome_session.find_element_by_xpath(
'//*[@id="btnSubmit"]'
).click()
def check_for_listings(self):
#code block
links = self.chrome_session.find_elements_by_class_name('link-record')
links = [(link.text, link.get_attribute('href').decode('utf-8'))
for link in links]
if len(links) == 0:
print("No work orders available at {0}".format(
datetime.datetime.now())
)
else:
for link_text, link_url in links:
print("Clicking work order {0} at {1}".format(link_text,datetime.datetime.now()))
self.chrome_session.get(link_url)
print("Attempting to accept at {0}".format(datetime.datetime.now()))
try:
self.chrome_session.find_element_by_xpath("//input[@value='Accept']").click()
try:
WebDriverWait(self.chrome_session, 1).until(EC.alert_is_present)
self.chrome_session.switch_to().alert().accept()
print("Accepted work order {0} at {1}.".format(link_text,datetime.datetime.now()))
except:
print "no alert"
except ElementNotVisibleException:
print("Accept input not found at {0}".format(datetime.datetime.now()))
self.chrome_session.back()
def main():
username = raw_input(
'Please enter the username of the GMail account you want to monitor.
>')
password = getpass.getpass(
'Please enter the password of the GMail account you want to monitor.
>')
ahsPassword = getpass.getpass('Please enter the password for ahs.
>')
ahs = AmericanHomesScraper(username, password, testing)
ahs.login(username,ahsPassword)
print("Starting script")
while True:
ahs.check_for_new_emails_from_sender([
'[email protected]',
'[email protected]',
])
if __name__ == '__main__':
main()
This correctly finds and clicks the "Accept" input button. After clicking accept, a javascript alert (Ok/Cancel) opens to confirm the acceptance. However, the script does not find the resulting alert. Or, at least it is not able to accept it because the exception is called.
As you can see, I have attempted to switch_to().alert()
, but that isn't working.
What am I doing wrong? Thank you so much for your help, I have been working on this for hours.
UPDATE
This code is running on a virtual server and does not use a UI. I just realized that the driver is PhantomJS, not Chrome. So, this is probably why it is failing. I have updated the question to reflect this.
I have tried the suggestions from similar questions, but it isn't working. The 3rd party site requires the alert confirmation to finish the process, but my script cannot see it because it is headless.
See Question&Answers more detail:
os