【问题标题】:Selenium python, Click only under certain conditionsSelenium python,仅在某些条件下单击
【发布时间】:2018-09-08 00:33:04
【问题描述】:

我的代码有效,但并非在所有情况下都有效 基本上功能是单击 load_more 按钮,直到它不再出现。

到目前为止,我只是有一个循环,它会找到加载更多按钮并单击它两次,但在某些情况下,当加载更多按钮消失时它会单击其他东西。

我打算做一个while循环,它会不断地找到点击load_more选项,直到loadmore消失然后打破循环。

这里是代码:(这只是找到并单击它两次)

load_more = browser.find_element_by_css_selector("#mainContent > div.left-panel > div > div.result-list > div > div.content")
WebDriverWait(browser, timeout).until(EC.visibility_of(load_more))

#Need bugfix, 
for i in range(2):
    browser.execute_script("return arguments[0].scrollIntoView(true);", load_more)
    ActionChains(browser).move_to_element(load_more).click().perform()

我在使用加载更多按钮时注意到。

<div class="progressbtnwrap" data-search-type="search" style="display: block;">

当网站上出现加载更多按钮时,该元素设置为“显示:块;”

但是一旦加载更多按钮消失,

<div class="progressbtnwrap" data-search-type="search" style="display: none;">

元素变为无,注意“display: none;”

有什么建议可以搜索这个吗?

在查看 selenium 文档时,我找不到任何方法来搜索此元素并专门检查样式是否被触发为无,

https://selenium-python.readthedocs.io/locating-elements.html

我的目标是创造这样的东西

while(True):
    if browser.find_element_by_notsurewhat == "block":
        ActionChains(browser).move_to_element(load_more).click().perform()
    if browser.find_element_by_notsurewhat == "none":
        break
    browser.execute_script("return arguments[0].scrollIntoView(true);", load_more)

我相信逻辑一定比这复杂得多,或者即使我想要实现的目标是可能的,任何建议都会很棒!

谢谢大家!

更新:

def load_more(browser):
    print("I'm in the function LOAD MORE")
    try:
        if browser.find_element_by_xpath('//*[@id="mainContent"]/div[1]/div/div[5]/div'):
            print("I HAVE ENTERED THE TRY BLOCK WITHIN THE LOAD MORE FUNCTION")
            return True
    except Exception as e:
        print(e)
        return False
    return False
while load_more(browser):
    print("I'm in the while loop!")
    ActionChains(browser).move_to_element(load_more).click().perform()
    browser.execute_script("return arguments[0].scrollIntoView(true);", load_more)

在放置我的定位和点击命令时,我开始收到以下错误:

Traceback (most recent call last):
  File "C:\Users\David\eclipse-workspace\Web_Scrap\setup.py", line 81, in <module>
    ActionChains(browser).move_to_element(load_more).click().perform()
  File "C:\Users\David\AppData\Local\Programs\Python\Python37\lib\site-packages\selenium\webdriver\common\action_chains.py", line 83, in perform
    action()
  File "C:\Users\David\AppData\Local\Programs\Python\Python37\lib\site-packages\selenium\webdriver\common\action_chains.py", line 293, in <lambda>
    Command.MOVE_TO, {'element': to_element.id}))
AttributeError: 'function' object has no attribute 'id'

我在试图找出程序崩溃的确切位置时注意到,一旦运行下面的代码,程序就会崩溃,但这在将其放入 while 循环或函数之前有效。 (我尝试在尝试之前将scrollIntoView,行放在函数内,并且收到类似的错误)。

ActionChains(browser).move_to_element(load_more).click().perform()
browser.execute_script("return arguments[0].scrollIntoView(true);", load_more)

【问题讨论】:

    标签: python python-3.x selenium selenium-webdriver selenium-chromedriver


    【解决方案1】:

    执行此操作的惯用方法是使用“显式等待”(AKA WebDriverWaitExpectedConditions)。

    以下将等到元素不再可见。如果它在 10 秒内没有消失,则会引发 TimeOutError

    from selenium.webdriver.support.ui import WebDriverWait
    from selenium.webdriver.support import expected_conditions as EC
    
    wait = WebDriverWait(driver, 10)
    element = wait.until(EC.invisibility_of_element_located(By.CLASS_NAME, 'progressbtnwrap'))
    

    【讨论】:

      【解决方案2】:

      如果 html 元素的样式属性设置为 display: none,selenium 将无法使用内置的 DOM 选择器函数(如 find_element_by_id/find_elements_by_class 等)找到该元素。 您可以简单地将查找操作包装在 try except 块中,并添加延迟以允许浏览器有时间进行 Ajax 调用。

      def load_more(browser):
          time.sleep(1)
          try:
              display = browser.execute_script("return document.getElementsByClassName('progressbtnwrap')[0].style.display")
              if display == 'none':
                  return False
              elem = browser.find_element_by_xpath('//div[contains(@class, "progressbtnwrap")]/div[contains(@class, "content")]')
              browser.execute_script("arguments[0].click();", elem)
              return True
          except Exception as e:
              print("Error")
              print(e)
          return False
      
      while load_more(browser):
          print("scrolling further")
      

      【讨论】:

      • 感谢您的解释,我非常感谢!,在尝试代码时,我确实收到了以下错误,消息:无效选择器:无法使用 xpath 表达式 /div[contains(@ class, "progressbtnwrap"] 因为以下错误:SyntaxError: Failed to execute 'evaluate' on 'Document': The string '/div[contains(@class, "progressbtnwrap"]' is not a valid XPath expression.跨度>
      • 我将回到元素部分并从那里复制 xpath 看看是否可行
      • 更正,我已经更新了 xpath 字符串中的错字。
      • 我尝试了更正,但功能遇到了异常,我已经从网站上复制了 xpath 并将其放入其中,并在我的帖子的更新部分收到错误:(
      • 另外,加载更多按钮本身是与我发布的 xpath 不同的元素,我发布的 xpath 是当加载更多按钮消失时更改名称的元素,我不确定这是否会有所不同,我会在帖子中张贴一张图片,以便您了解我在说什么
      【解决方案3】:

      假设您目前只是想找到一种检查元素当前样式的方法,您可以使用此代码。

      driver.execute_script("return arguments[0].style.display;", load_more)
      

      您可以使用检查当返回值是“无”几秒钟,这意味着不会加载更多数据时,您可以退出循环。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-04-10
        • 1970-01-01
        • 1970-01-01
        • 2021-10-07
        • 2020-07-30
        • 1970-01-01
        相关资源
        最近更新 更多