【问题标题】:Selenium not finding elements PythonSelenium 找不到元素 Python
【发布时间】:2019-11-17 21:20:20
【问题描述】:

我在 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,它返回td标签的数量lsm2

以及源页面外观的图片

这个返回0,由于某种原因它没有找到类lsm2Nowgoal Serie A的标签,还有一张感兴趣的片段的图片 即使我尝试使用这条注释行 a_ = driver.find_elements_by_class_name('lsm2') 直接找到它,它仍然返回 0。我将不胜感激。

【问题讨论】:

    标签: python selenium-webdriver web-scraping web-crawler selenium-chromedriver


    【解决方案1】:

    据我了解,带有“showRound” id 的 td 的内部 HTML 是动态的,由 showRound() JS 函数加载,然后调用该函数通过页面加载时页面的 head 标记内的脚本。因此,在您的情况下,它似乎没有足够的时间来加载。我尝试通过两种方式解决此问题:

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

    2. 我们可以等待“lsm2”类的第一个元素加载;如果在合理的超时后仍未这样做,我们可能会停止等待并引发异常(感谢 Zeinab Abbasimazar 的回答 here)。这可以通过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 循环进行迭代,但这取决于你。

    【讨论】:

      猜你喜欢
      • 2021-12-17
      • 2018-11-07
      • 2019-06-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多