2

Ich bin neu in Python, aber müssen Code von jemand anderem erstellt ändern. Ich bin nicht in der Lage den vollständigen Code zu schreiben, aber ich gepostet die meisten davon unter:Python klicken Sie auf Schaltfläche bei Alarm

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.\n>') 
    password = getpass.getpass(
     'Please enter the password of the GMail account you want to monitor.\n>') 
    ahsPassword = getpass.getpass('Please enter the password for ahs. \n>') 
    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() 

Diese richtig findet und klickt auf den „Accept“ Eingabe-Taste. Nachdem Sie auf "Akzeptieren" geklickt haben, wird eine JavaScript-Benachrichtigung (Ok/Abbrechen) geöffnet, um die Annahme zu bestätigen. Das Skript findet jedoch die resultierende Warnung nicht. Oder es ist zumindest nicht in der Lage, es zu akzeptieren, weil die Ausnahme aufgerufen wird.

Wie Sie sehen können, habe ich versucht, switch_to().alert(), aber das funktioniert nicht.

Was mache ich falsch? Vielen Dank für Ihre Hilfe, ich arbeite seit Stunden daran.

UPDATE

Dieser Code auf einem virtuellen Server ausgeführt wird und keine Benutzeroberfläche verwenden. Ich habe gerade festgestellt, dass der Treiber PhantomJS ist, nicht Chrome. Das ist wahrscheinlich der Grund warum es versagt. Ich habe die Frage aktualisiert, um dies zu berücksichtigen.

Ich habe die Vorschläge von ähnlichen Fragen versucht, aber es funktioniert nicht. Die 3rd-Party-Site benötigt die Alarmbestätigung, um den Prozess zu beenden, aber mein Skript kann es nicht sehen, weil es kopflos ist.

+0

atleast die URL geben –

+0

http://selenium-python.readthedocs.io /api.html#selenium.webdriver.remote.webdriver.WebDriver.switch_to_alert – Bahrom

+0

Mögliches Duplikat von [Klicken Sie auf das Javascript-Popup durch Webdriver] (https://stackoverflow.com/questions/8631500/click-the-java Skript-Popup-through-webdriver) – Bahrom

Antwort

1

Ich weiß nicht, ob der folgende Code Ihnen helfen wird, an einem Punkt habe ich das gleiche Problem konfrontiert und endete auf eine Warnung warten und dann die Warnung akzeptieren, arbeitete für mich.

from selenium.common.exceptions import NoAlertPresentException, 

    def wait_for_alert(self): 

     for i in range(50): 
      try: 
       alert = chrome_session.switch_to.alert 
       if alert.text: 
        break 
      except NoAlertPresentException: 
       pass 
      time.sleep(.25) 
     else: 
      raise NoAlertPresentException("Alert visibility timed out") 
    return alert 

wait_for_alert().accept() 
+0

Dies implementiert nur einen Teil des expliziten Wartens von WebDriver. –

+0

Sie haben Recht und dies ist der Weg, den ich genommen habe und nicht das explizite Warten, nachdem ich gesagt habe, dass es in meinem Fall eine Verzögerung zwischen der Aktion und der Alarmanzeige gab und mein Code funktionierte. – Satish

+0

Super Code, würde ich jedoch vorschlagen, die Selen WebDriver warten, ob implizit oder explizit. Hier ist die Referenzen: http://selenium-python.readthedocs.io/waits.html# –

2

Ein paar Punkte hier:

  • switch_to_alert so veraltet war haben wir obligatorische Verwendung switch_to().alert()
  • scheint mir rein Timing-Problem. Daher brauchen wir ExplicitWait dh WebDriverWait mit expected_conditions Klausel alert_is_present gesetzt zu induzieren, wie folgt:

    from selenium.webdriver.support import expected_conditions as EC 
    #code block 
    self.chrome_session.find_element_by_xpath("//input[@value='Accept']").click() 
    WebDriverWait(self.chrome_session, 10).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())) 
    
+0

Ich habe versucht, dies, aber es hängt nur. keine Nachrichten, keine Fehler. – davids

+0

ich habe die meisten der Code nun veröffentlicht, um zu sehen, ob es – davids

+0

hilft mir klar, dass es PhantomJS verwendet, nicht Chrome. So erscheint der Alarm nie wirklich, wenn das Skript Aber ich kann mein Ziel nicht erreichen, ohne auf das Akzeptieren zu klicken. Wie gehe ich damit um? – davids

Verwandte Themen