【问题标题】:how to use time sleep to make selenium output consistent如何使用时间睡眠使硒输出一致
【发布时间】:2021-08-02 12:33:32
【问题描述】:

这可能是我问过的最愚蠢的问题,但这让我发疯了......

基本上我想从配置文件中获取所有链接,但由于某种原因,selenium 在大多数情况下会提供不同数量的链接(有时所有链接有时只有十分之一)

我尝试了 time.sleep,我知道它会以某种方式影响输出,但我不明白问题出在哪里。 (但这只是我的假设,也许那是错误的)

我没有其他解释为什么我得到不一致的输出。由于我不时获得所有个人资料链接,因此该程序能够找到所有相关的个人资料。

输出应该是什么(针对不同的 gui 输入)

输入:anlagenbau 输出:3070

Fahrzeugbau 输出:4065

激光输出:1311



from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait
from selenium.common.exceptions import TimeoutException
from urllib.request import urlopen
from datetime import date
from datetime import datetime
import easygui
import re
from selenium.common.exceptions import NoSuchElementException
import time

#input window suchbegriff
suchbegriff = easygui.enterbox("Suchbegriff eingeben | Hinweis: suchbegriff sollte kein '/' enthalten")

#get date and time
now = datetime.now()
current_time = now.strftime("%H-%M-%S")
today = date.today()
date = today.strftime("%Y-%m-%d")

def get_profile_url(label_element):
    # get the url from a result element
    onlick = label_element.get_attribute("onclick")
    # some regex magic
    return re.search(r"(?<=open\(\')(.*?)(?=\')", onlick).group()


def load_more_results():
    # load more results if needed // use only on the search page!
    button_wrapper = wd.find_element_by_class_name("loadNextBtn")
    button_wrapper.find_element_by_tag_name("span").click()


#### Script starts here ####

# Set some Selenium Options
options = webdriver.ChromeOptions()
options.add_argument("--no-sandbox")
options.add_argument("--disable-dev-shm-usage")

# Webdriver
wd = webdriver.Chrome(options=options)
# Load URL
wd.get("https://www.techpilot.de/zulieferer-suchen?"+str(suchbegriff))


# lets first wait for the timeframe
iframe = WebDriverWait(wd, 5).until(
    EC.frame_to_be_available_and_switch_to_it("efficientSearchIframe")
)

# the result parent
result_pane = WebDriverWait(wd, 5).until(
    EC.presence_of_element_located((By.ID, "resultPane"))
)

#get all profilelinks as list
time.sleep(5)
href_list = []
wait = WebDriverWait(wd, 15)

while True:
    try:
        #time.sleep(1)
        wd.execute_script("loadFollowing();")
        #time.sleep(1)
        try:
            wait.until(EC.presence_of_all_elements_located((By.CSS_SELECTOR, ".fancyCompLabel")))
        except TimeoutException:
            break
        #time.sleep(1) # beeinflusst in irgeneiner weise die findung der ergebnisse
        result_elements = wd.find_elements_by_class_name("fancyCompLabel")
        #time.sleep(1)
        for element in result_elements:
            url = get_profile_url(element)
            href_list.append(url)
        #time.sleep(2)
        while True:
            try:
                element = wd.find_element_by_class_name('fancyNewProfile')
                wd.execute_script("""var element = arguments[0];element.parentNode.removeChild(element);""", element)
            except NoSuchElementException:
                break
            
    except NoSuchElementException:
        break

wd.close #funktioniert noch nicht
print("####links secured: "+str(len(href_list)))

【问题讨论】:

    标签: selenium sleep


    【解决方案1】:

    由于您说睡眠会影响结果的数量,因此听起来它们是异步加载并在加载时填充,而不是一次全部填充。

    第一个问题是您是否可以要求网站开发人员更改此设置,仅在它们一次全部加载时才显示它们。

    假设您与他们不在同一家公司工作,请考虑:

    • 页面上是否还有其他内容在全部加载后显示?例如,它可以是按钮或状态消息。您可以等待该项目出现,然后然后获取列表吗?
    • 新项目出现的频率如何?您可以相对不频繁地轮询结果数量,例如每 2 或 3 秒一次,然后在连续两次获得相同数量的结果时考虑所有结果。

    【讨论】:

      【解决方案2】:

      问题是presence_of_all_elements_located 方法不会等待与传递的定位器匹配的所有元素。它等待至少存在 1 个与传递的定位器匹配的元素,然后返回在该时刻在页面上找到的与该定位器匹配的元素列表。
      在Java中我们有

      wait.until(ExpectedConditions.numberOfElementsToBeMoreThan(element, expectedElementsAmount));
      

      wait.until(ExpectedConditions.numberOfElementsToBe(element, expectedElementsAmount));
      

      使用这些方法,您可以等待预定义数量的元素出现等。
      带有 Python 的 Selenium 不支持这些方法。
      在 Python 中使用 Selenium 唯一可以看到的是构建一些自定义方法来执行这些操作。
      因此,如果您希望页面上出现/呈现一定数量的元素/链接等,您可以使用这种方法。
      这将使您的测试稳定并避免使用硬编码的睡眠。
      UPD
      我找到了this 解决方案。
      这看起来是上述方法的解决方案。
      这似乎是 wait.until(ExpectedConditions.numberOfElementsToBeMoreThan(element, expectedElementsAmount)); 的 Python 等价物

      myLength = 9
      WebDriverWait(browser, 20).until(lambda browser: len(browser.find_elements_by_xpath("//img[@data-blabla]")) > int(myLength))
      

      还有这个

      myLength = 10
      WebDriverWait(browser, 20).until(lambda browser: len(browser.find_elements_by_xpath("//img[@data-blabla]")) == int(myLength))
      

      等效于 Java wait.until(ExpectedConditions.numberOfElementsToBe(element, expectedElementsAmount));

      【讨论】:

        猜你喜欢
        • 2022-01-12
        • 2018-03-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-10-04
        • 2014-03-12
        • 1970-01-01
        • 2021-04-12
        相关资源
        最近更新 更多