2016-11-24 108 views
3

我试图在this网站,了解一些自动化测试程序中切换的国家,价格在每个国家不同的,所以我编程一个小工具来帮助我决定在哪里买的起。硒蟒蛇点击A HREF通过文本中

首先,我得到的所有的货币到列表中做这样的:

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 

例如,它返回:['United Kingdom', 'United States', 'France', 'Deutschland', 'España', 'Australia', 'Россия']然后,我遍历列表并且每次调用这个函数:

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")) 
     except StaleElementReferenceException: 
      set_country(text) 

当比较a.text于文字,我得到了StaleElementReferenceException,我看网上,这意味着对象从当我救了它一变,一个简单的办法就是再次调用该函数。然而,我不喜欢这个解决方案和这个代码很多,我认为它不是有效的,需要太多时间,有什么想法?

编辑:

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

你改变你每次都送** driver.get时间的网页** **中如果a.text =文本**条件。所以,当DOM更新一次** driver.get **时,原始页面会丢失。 –

回答

2

如果我理解正确的问题说明,添加break声明解决了这个问题:

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被更新一次driver.get被调用。所以与旧页面相关的引用(即,a_tags)将不起作用。

取而代之的是,you should break the loop,一旦条件满足,只要使用driver.get检索给定的国家/地区页面即可出来。所以,你设置你想要的国家,没有必要重复一遍又一遍,以检查条件,这显然导致StaleElementReferenceException

+1

太好了,谢谢 – DAVIDBALAS1

0

如果你那些陈旧的元素是a标签,而不是div,你可以遍历一个标签长度和打通div每个元素的文本:

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")) 

这样你就可以从DOM中获取最新的元素。

如果您的陈旧元素是div,那么您需要验证下拉列表在您的one.click()盘旋或其他方式后不会消失。

另一种方法是改变你的a.text有一个等待:

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

谢谢你,我会尝试,后来当我会在我的计算机,另一个问题是,你觉得获得的国家名单首先是一个很好的事情,或者有一个主要的功能是通过国家的长度迭代,每次点击不同的国家并获得价格? – DAVIDBALAS1

+0

我想选择一个,如果过时的元素是,它仍然没有工作,所以我想这是div,但是,我不明白您的解决方案。 – DAVIDBALAS1

+0

我们试着澄清一下情况:首先你说它是用于自动化测试的,但是从描述中我发现你试图从一个叫做“scraping”的网站自动获取信息,这需要一种不同的方法,上午我对吗?如果是这样,你更好的选择将迭代在一个主要功能,并每次点击货币,而不是首先得到一个列表,因为它可能会导致陈旧的元素。我建议的另一件事是在调试中一行一行地打开浏览器,看看会发生什么,并了解究竟是什么导致异常。 – Moshisho