selenium python通过内部文本单击a href
我试图在一些自动化测试网站上以编程方式切换国家,每个国家的价格都不一样,所以我正在编程一个小工具来帮助我决定从哪里购买 首先,我通过以下操作将所有货币放入列表:selenium python通过内部文本单击a href,python,selenium,Python,Selenium,我试图在一些自动化测试网站上以编程方式切换国家,每个国家的价格都不一样,所以我正在编程一个小工具来帮助我决定从哪里购买 首先,我通过以下操作将所有货币放入列表: def get_all_countries(): one = WebDriverWait(driver1, 10).until(EC.element_to_be_clickable((By.CLASS_NAME, "selected-currency"))) one.click() el = WebDriverW
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
例如,它返回:[‘英国’、‘美国’、‘法国’、‘德国’、‘埃斯帕尼亚’、‘澳大利亚’、‘П砦砦砦砦砦’]
,然后,我遍历列表,每次调用此函数时:
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和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')
如果过时元素是
a
标记而不是div
,则可以迭代a标记的长度,并通过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之后是否消失。单击()
,将其悬停或以其他方式
另一种方法是将a.text
更改为等待:
wait = WebDriverWait(driver, 10, poll_frequency=1, ignored_exceptions=[StaleElementReferenceException])
a = wait.until(EC.text_to_be_present_in_element((By.YourBy)))
如果我正确理解问题陈述,添加
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
更新一次驱动程序。调用get
。因此,与旧页面相关的引用(即a_标记)将不起作用
相反,
您应该打破循环
并在使用驱动程序检索到给定的国家/地区页面后立即出来。满足条件后获取
。因此,您设置了所需的国家/地区,无需反复检查是否存在条件,这显然会导致StaleElementReferenceException
谢谢,我稍后在靠近计算机时会尝试,另一个问题是,你认为首先获取国家列表是一件好事吗?还是有一个主要功能可以遍历国家的长度,每次单击不同的国家并获取价格?我尝试了选项一,如果过时的元素是a,它仍然不起作用,那么我想它是div,但是,我还不明白你的解决方案。让我们试着澄清一下这个场景:首先你说它是用于自动化测试的,但是从描述中我看到你试图从一个叫做“抓取”的网站上自动获取信息,这需要一种不同的方法,对吗?如果是这样的话,更好的选择是在一个主函数中迭代,每次单击货币,而不是首先获取列表,因为它可能会导致过时的元素。我建议的另一件事是在浏览器打开的情况下逐行运行调试,以查看发生了什么,并了解异常的确切原因。好的,那么你是对的,我认为你试图用selenium做的任何事情都是自动化测试,我正在尝试进行刮片。无论如何,我将代码更新为一个主函数,现在StaleElementReferenceException在这一行:atext=a.text。我还尝试更改代码,并且每次都再次获取a引用,因此我不会得到此错误,但我失败了。您在每次发送driver.get if a.text=text条件时都在更改网页。因此,在调用driver.get后,当DOM更新时,原始页面将丢失。