这是我关于Stack Overflow的第一篇文章。我一直在SO上浏览和搜索这个问题的每一个可能的答案,我想现在我应该问一个问题,因为我已经在这堵墙上呆了好几天了。我目前正在Python中使用Selenium进行一个web抓取项目。我已经浏览了一个网站,目前正在浏览第二个网站,我遇到了一个看似棘手的问题。以下代码运行良好,页面上没有错误https://www.spd.de/standpunkte/:
try:
driver.find_element_by_link_text("Familien").click()
except NoSuchElementException:
WebDriverWait(driver, 12).until("Familien").click()
同时,以下代码在页面上抛出错误TypeError: 'str' object is not callable
https://www.spd.de/standpunkte/familie/:
try:
driver.find_element_by_link_text("Mehr erfahren").click()
except NoSuchElementException:
WebDriverWait(driver, 12).until("Mehr erfahren").click()
错误发生在线路WebDriverWait(driver, 12).until("Mehr erfahren").click()
上。根据我到目前为止的研究,我认为具体的问题是,这一行中的某个对象被解释为str
对象,因此无法调用。在我看来,有两个问题:
我看不出这一行产生错误的任何原因,而顶部的代码,抓取相同的网站,但在不同的页面上,工作时没有问题。我检查并确保页面上没有被点击的隐藏元素。
我不知道行中的什么被当作
str
对象处理。整条线?只是其中的一部分?如果是,是哪一部分?更糟糕的是,我真的无法打破界限去了解它;CCD_ 5和CCD_。我能够确定.click()
方法不是问题所在,因为我尝试将行设置为等于变量,然后与变量交互,但这仍然在与以前相同的行上产生错误;它甚至从未达到CCD_ 8方法的水平。
有什么方法可以确定行的哪一部分被解释为str
吗?或者这就是问题所在?
这已经让我发疯了,所以非常感谢您的帮助!
我想我在这里发现了你的问题。来自源
def until(self, method, message=''):
...
until
采用一种方法(即可调用的东西(。因此,当driver.find_element_by_link_text("Mehr erfahren").click()
引发异常时,它将尝试调用...until("Mehr erfahren")...
。由于until
期望一个方法,它会尝试调用你给它的字符串,从而引发让你抓狂的错误:(
我认为until需要一个条件(WebDriverWait等待该条件为true(。您只是传递一个字符串作为参数,而不是条件。您需要一个条件来检查页面上是否存在该元素。
您可以使用这个css选择器:a[href*="familien"]
这可以用于您的两个URL。
driver.get('yourURL')
try:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, 'a[href*="familien"]'))).click()
except NoSuchElementException:
# handle if the element not exist
print('element not exist')
请参阅此处的文档,了解如何使用WebDriverWait
您的研究方向是正确的。
在您的第一个用例中,try
中的行是成功的:
driver.find_element_by_link_text("Familien").click()
因此except
中的线路从未被调用:
WebDriverWait(driver, 12).until("Familien").click()
因此,您不会看到错误。
在您的第二个用例中,try
中的行不成功:
driver.find_element_by_link_text("Familien").click()
因此except
内的线路被称为:
WebDriverWait(driver, 12).until("Mehr erfahren").click()
导致错误:
TypeError: 'str' object is not callable
深潜
WebDriverWait与expected_conditions一起调用。
你可以在中找到一些详细的讨论
- 如何在python中休眠webdriver数毫秒
- WebDriverWait未按预期工作
现在,element_to_be_clickable()
应该在tuple
中调用,因为它不是函数而是类,其中初始值设定项只期望隐式self之外的1参数:
class element_to_be_clickable(object):
""" An Expectation for checking an element is visible and enabled such that you can click it."""
def __init__(self, locator):
self.locator = locator
def __call__(self, driver):
element = visibility_of_element_located(self.locator)(driver)
if element and element.is_enabled():
return element
else:
return False
所以不是:
WebDriverWait(driver, 12).until("Mehr erfahren").click()
您需要(添加一个额外的括号(:
WebDriverWait(driver, 12).until((EC.element_to_be_clickable(By.LINK_TEXT, "Mehr erfahren"))).click()
您可以在init((中找到详细的讨论,它采用了2个位置参数,但使用WebDriverWait和expected_conditions作为element_to_be_clickleable与Selenium Python 给出了3个位置参数