2016-11-24 4 views
3

Ich versuche, Länder programmatisch in this Website für einige Automatisierung testen, sind die Preise in jedem Land anders, so dass ich ein kleines Werkzeug zu programmieren, um mir zu entscheiden, wo man kaufen.Selen Python Klicken Sie auf eine href durch Text innerhalb

Zuerst bekomme ich alle Währungen in eine Liste, indem Sie diese:

def get_all_countries(): 
    one = WebDriverWait(driver1, 10).until(EC.element_to_be_clickable((By.CLASS_NAME, "selected-currency"))) 
    one.click() 
    el = WebDriverWait(driver1, 10).until(EC.visibility_of_element_located((By.CLASS_NAME, "site-selector-list"))) 
    list_return = [] 
    a_tags = el.find_elements_by_tag_name('a') 
    for a in a_tags: 
     list_return.append(a.text) 
    return list_return 

Zum Beispiel, gibt sie: ['United Kingdom', 'United States', 'France', 'Deutschland', 'España', 'Australia', 'Россия'] und dann, ich iterieren durch die Liste und jedes Mal, dem Aufruf dieser Funktion:

Beim Vergleich von a.text mit Text habe ich eine StaleElementReferenceException erhalten. Ich habe online gelesen, dass das Objekt geändert wurde, als ich es gespeichert habe, und eine einfache Lösung besteht darin, die Funktion erneut aufzurufen. Allerdings mag ich diese Lösung und diesen Code nicht sehr, ich denke, es ist nicht effektiv und braucht zu viel Zeit, irgendwelche Ideen?

EDIT:

def main(url): 
    driver1.get(url) 
    to_return_string = '' 
    one = WebDriverWait(driver1, 10).until(EC.element_to_be_clickable((By.CLASS_NAME, "selected-currency"))) 
    one.click() 
    el = WebDriverWait(driver1, 10).until(EC.visibility_of_element_located((By.CLASS_NAME, "site-selector-list"))) 
    a_tags = el.find_elements_by_tag_name('a') 
    for a in a_tags: 
     atext = a.text 
     ahref = a.get_attribute('href') 
     try: 
      is_change_currency_displayed = driver1.find_element_by_id("siteSelectorList").is_displayed() 
      if not is_change_currency_displayed: # get_all_countries function leaves dropdown open. 
       one = WebDriverWait(driver1, 10).until(EC.element_to_be_clickable((By.CLASS_NAME, "selected-currency"))) 
       one.click() 
      driver1.get(ahref) 
      current_price = WebDriverWait(driver1, 10).until(
       EC.visibility_of_element_located((By.CSS_SELECTOR, ".current-price"))) 
      to_return_string += ("In " + atext + " : " + current_price.text + ' \n') 
      print("In", atext, ":", current_price.text) 
     except TimeoutException: 
      print("In", atext, ":", "Timed out waiting for page to load") 
      to_return_string += ("In " + atext + " : " + " Timed out waiting for page to load" + ' \n') 
    return to_return_string 


main('http://us.asos.com/asos//prd/7011279') 
+0

Sie ändern die Webseite jedes Mal, wenn Sie ** driver.get ** in ** wenn a.text = Text ** senden. Die ursprüngliche Seite geht verloren, sobald DOM aktualisiert wird. ** driver.get ** wird aufgerufen. –

Antwort

2

Wenn ich das Problem Aussage richtig, Hinzufügen break Anweisung löst das Problem verstehen:

def set_country(text): 
    is_change_currency_displayed = driver1.find_element_by_id("siteSelectorList").is_displayed() 
    if not is_change_currency_displayed: # get_all_countries function leaves dropdown open. Check if it is open before clicking it. 
     one = WebDriverWait(driver1, 10).until(EC.element_to_be_clickable((By.CLASS_NAME, "selected-currency"))) 
     one.click() 
    div = WebDriverWait(driver1, 10).until(EC.visibility_of_element_located((By.CLASS_NAME, "site-selector-list"))) 
    a_tags = div.find_elements_by_tag_name('a') 
    for a in a_tags: 
     try: 
      if a.text == text: 
       driver1.get(a.get_attribute("href")) 
       break 
     except StaleElementReferenceException: 
      set_country(text) 

DOM wird aktualisiert, sobald aufgerufen wird. Daher funktionieren die Referenzen, die sich auf die alte Seite beziehen (d. h. a_tags), nicht.

Stattdessen you should break the loop und kommen heraus, sobald die angegebene Landseite mit driver.get abgerufen wird, sobald die Bedingung erfüllt ist. Sie legen also das gewünschte Land fest und müssen nicht immer wieder iterieren, um zu prüfen, ob die Bedingung offensichtlich zu StaleElementReferenceException führt.

+1

Großartig, danke – DAVIDBALAS1

0

Wenn Ihr abgestanden Element ist die a Tag und nicht die div, können Sie über die eine Tags Länge durchlaufen und jedes Element des Textes durch die div erhalten:

for i in range(len(div.find_elements_by_tag_name('a')): 
    if div.find_elements_by_tag_name('a')[i].text == text: 
     driver1.get(div.find_elements_by_tag_name('a')[i].get_attribute("href")) 

Auf diese Weise können Sie das neueste Element aus dem DOM.

Wenn Ihr veraltetes Element die div ist, dann müssen Sie sicherstellen, dass das Dropdown nicht nach one.click() mit dem Schweben es oder auf andere Weise verschwindet.

würde Ein weiterer Ansatz, um Ihre a.text zu ändern, um eine Wartezeit haben:

wait = WebDriverWait(driver, 10, poll_frequency=1, ignored_exceptions=[StaleElementReferenceException]) 
a = wait.until(EC.text_to_be_present_in_element((By.YourBy))) 
+0

Danke, ich werde das später versuchen, wenn ich in der Nähe meines Computers bin, eine andere Frage ist, denken Sie, die Liste der Länder zuerst zu bekommen, ist eine gute Sache oder eine Hauptfunktion zu haben, die durch die Länge von Ländern iteriert, jedes Mal klickt ein anderes Land und erhält den Preis? – DAVIDBALAS1

+0

Ich habe Option 1 ausprobiert, wenn das veraltete Element ein ist, und es funktioniert immer noch nicht, also denke ich, es ist das Div, aber ich habe Ihre Lösung nicht verstanden. – DAVIDBALAS1

+0

Lassen Sie uns versuchen, das Szenario zu klären: Zunächst einmal sagten Sie es für Automatisierungstests, aber von der Beschreibung sehe ich, dass Sie versuchen, Informationen automatisch von einer Website zu erhalten, die "Scraping" genannt wird und dies erfordert einen anderen Ansatz, bin Ich richtig? Wenn dies der Fall ist, besteht Ihre bessere Option darin, in einer Hauptfunktion zu iterieren und jedes Mal auf die Währung zu klicken, anstatt zuerst eine Liste zu erhalten, da dies veraltete Elemente verursachen kann. Eine andere Sache, die ich vorschlagen würde, ist in Debug debuggen Zeile für Zeile mit dem Browser geöffnet, um zu sehen, was passiert und verstehen, was genau die Ausnahme verursacht. – Moshisho

Verwandte Themen