繁体   English   中英

Selenium 未找到元素 Python

[英]Selenium not finding elements Python

我在 selenium 中编写了一个代码来提取足球联赛中的回合数,我所看到的所有页面的所有元素都是相同的,但由于某种原因,该代码适用于某些链接而不适用于其他链接。

from selenium import webdriver
from selenium.webdriver.firefox.options import Options
from time import sleep

def pack_links(l):

    options = Options()
    options.headless = True
    driver = webdriver.Chrome()
    driver.get(l)

    rnds = driver.find_element_by_id('showRound')
    a_ = rnds.find_elements_by_xpath(".//td[@class='lsm2']")
    #a_ = driver.find_elements_by_class_name('lsm2')

    knt = 0
    for _ in a_:
        knt = knt+1

    print(knt)

    sleep(2)
    driver.close()
    return None

link = 'http://info.nowgoal.com/en/League/34.html'
pack_links(link)

这是一个适用于 Nowgoal Serie B的链接,它返回带有 class lsm2td标签的数量

以及源页面外观的图片在此处输入图像描述

而这个返回 0,由于某种原因,它没有找到带有 class lsm2 Nowgoal Serie A的标签,还有一张感兴趣的片段的图片在此处输入图像描述 即使我试图用这条注释线直接找到它a_ = driver.find_elements_by_class_name('lsm2')它仍然返回 0。我将不胜感激。

据我了解,带有“showRound” id 的td的内部 HTML 是动态的,并由showRound() JS function 加载,而后者又由页面加载时页面头部标签中的脚本调用。 因此,在您的情况下,它似乎没有足够的时间来加载。 我试图通过两种方式解决这个问题:

  1. 一个杂牌:使用driver.implicitly_wait(number_of_seconds_to_wait) 我还建议将来使用它而不是sleep() 然而,这个解决方案相当笨拙并且有点异步。 换句话说,它主要等待秒倒计时而不是结果。

  2. 我们可以等待第一个带有 "lsm2" class 的元素加载; 如果在合理的超时后仍未这样做,我们可能会停止等待并引发异常(感谢Zeinab Abbasimazar此处的回答)。 这可以通过expected_conditionsWebDriverWait来实现:

from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from selenium.common.exceptions import TimeoutException

def pack_links(l):
    options = webdriver.ChromeOptions()  # I would also suggest to use this instead of Options()
    options.add_argument("--headless")
    options.add_argument("--enable-javascript")  # To be on the safe side, although it seems to be enabled by default
    driver = webdriver.Chrome("path_to_chromedriver_binary", options=options)
    driver.get(l)
    rnds = driver.find_element_by_id('showRound')

    """Until now, your code has gone almost unchanged. Now let's wait for the first td element with lsm2 class to load, with setting maximum timeout of 5 seconds:"""

    try:
        WebDriverWait(driver, 5).until(EC.presence_of_element_located((By.CLASS_NAME, "lsm2")))
        print("All necessary tables have been loaded successfully")
    except TimeoutException:
        raise("Timeout error")


    """Then we proceed in case of success:"""

    a_ = rnds.find_elements_by_xpath(".//td[@class='lsm2']")
    knt = 0
    for _ in a_:
        knt = knt+1

    print(knt)

    driver.implicitly_wait(2)  # Not sure if it is needed here anymore
    driver.close()
    driver.quit()  # I would also recommend to make sure you quit the driver not only close it if you don't want to kill numerous RAM-greedy Chrome processes by hand 
    return None

您可以进行一些实验并调整您需要的超时长度以获得必要的结果。 我还建议使用len(a_)而不是使用for循环进行迭代,但这取决于您。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM