硒蟒蛇,仅在特定条件下单击

时间:2018-09-08 00:33:05

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

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

到目前为止,我只是有一个循环,它找到loadmore按钮并单击两次,但是在某些情况下,当load more按钮消失时,它将单击其他内容。

我正计划制作一个while循环,它将不断找到click 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;">

该元素更改为无,请注意“显示:无;”

关于如何搜索此内容的任何建议?

在浏览硒文档时,我找不到任何搜索此元素的方法,尤其是检查是否将样式触发为无,

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)

Load more button visible

Load more button Gone

3 个答案:

答案 0 :(得分:2)

惯用的方法是使用“显式等待”(又称为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'))

答案 1 :(得分:1)

如果将html元素的style属性设置为显示:none,则硒将无法使用内置的DOM选择器功能(例如find_element_by_id / find_elements_by_class等)来查找元素。 您可以简单地将find操作包装在try try块中,并添加一个延迟时间,以使浏览器有时间进行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")

答案 2 :(得分:0)

假设您当前正在尝试寻找一种方法来检查元素的当前样式,那么可以使用此代码。

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

您可以用来检查,如果返回值在数秒内为“ none”(无),这意味着将不再加载任何数据,则可以退出循环。