如何使用 Selenium 等待页面上的元素可见(然后转到其他内容)?

Posted

技术标签:

【中文标题】如何使用 Selenium 等待页面上的元素可见(然后转到其他内容)?【英文标题】:How can I use Selenium to wait for an element to be visible on a page (but then move on to something else)? 【发布时间】:2022-01-23 23:13:39 【问题描述】:

我正在尝试从网页中抓取 URL,它们位于排名表内,需要几秒钟才能加载。

我想做的是等到排名表完成加载,然后通过它的 id 抓取它并遍历元素。

这是我用来抓取页面并等待的代码:

    driver = webdriver.Chrome(cred_path)
    driver.get(page)

    wait(driver, 5).until(EC.presence_of_element_located((By.ID, 'sc-ljMRFG hgfcNB rankings-table')))
    #soup = BeautifulSoup(driver.page_source, features='lxml')
    #print(soup.prettify())
    rankings = soup.find_all('div', 'class': "sc-ljMRFG hgfcNB rankings-table")[0] 

    print(rankings)

据我所知,代码实际上一直在运行(我可以在窗口打开时直观地看到表格正在加载),但随后会引发超时错误:

    Traceback (most recent call last):
  File "ethereum_scraper_dappRadarv2.py", line 377, in <module>
    general_dapp_page()
  File "ethereum_scraper_dappRadarv2.py", line 39, in general_dapp_page
    _ = wait(driver, 5).until(EC.visibility_of_element_located((By.ID, 'sc-ljMRFG hgfcNB rankings-table')))
  File "/Users/trentfowler/opt/anaconda3/lib/python3.8/site-packages/selenium/webdriver/support/wait.py", line 89, in until
    raise TimeoutException(message, screen, stacktrace)
selenium.common.exceptions.TimeoutException: Message: 
Stacktrace:
0   chromedriver                        0x0000000104dd4269 __gxx_personality_v0 + 582729
1   chromedriver                        0x0000000104d5fc33 __gxx_personality_v0 + 106003
2   chromedriver                        0x000000010491ce28 chromedriver + 171560
3   chromedriver                        0x00000001049523d2 chromedriver + 390098
4   chromedriver                        0x0000000104952591 chromedriver + 390545
5   chromedriver                        0x00000001049846b4 chromedriver + 595636
6   chromedriver                        0x000000010496f9fd chromedriver + 510461
7   chromedriver                        0x0000000104982462 chromedriver + 586850
8   chromedriver                        0x000000010496fc23 chromedriver + 511011
9   chromedriver                        0x000000010494575e chromedriver + 337758
10  chromedriver                        0x0000000104946a95 chromedriver + 342677
11  chromedriver                        0x0000000104d908ab __gxx_personality_v0 + 305803
12  chromedriver                        0x0000000104da7863 __gxx_personality_v0 + 399939
13  chromedriver                        0x0000000104dacc7f __gxx_personality_v0 + 421471
14  chromedriver                        0x0000000104da8bba __gxx_personality_v0 + 404890
15  chromedriver                        0x0000000104d84e51 __gxx_personality_v0 + 258097
16  chromedriver                        0x0000000104dc4158 __gxx_personality_v0 + 516920
17  chromedriver                        0x0000000104dc42e1 __gxx_personality_v0 + 517313
18  chromedriver                        0x0000000104ddb6f8 __gxx_personality_v0 + 612568
19  libsystem_pthread.dylib             0x00007fff205d18fc _pthread_start + 224
20  libsystem_pthread.dylib             0x00007fff205cd443 thread_start + 15

(请注意,据我所知,后续的rankings =print 语句不会执行)

我目前的解释是 selenium 执行 wait 命令很好,但随后超时,因为没有直接给它进一步的指令(即我没有在任何事情上调用 click())。

我有 RTFM,但 selenium 文档非常稀少。真的没有等到元素加载然后继续其他处理任务的概念吗?我是否必须以某种方式与元素交互,如果是这样,考虑到我真正想要的只是迭代内部元素,那么最好的交互方式是什么?

【问题讨论】:

能否包含完整的错误信息? @AlarmClockMan 添加。 【参考方案1】:

可能您使用了错误的定位器,因为 sc-ljMRFG hgfcNB rankings-table 不能是 ID 属性的值,但可能是 class 属性的值。

如此有效地你需要改变:

wait(driver, 5).until(EC.presence_of_element_located((By.ID, 'sc-ljMRFG hgfcNB rankings-table')))

诱导WebDriverWait为visibility_of_element_located(),你可以使用以下Locator Strategies之一:

使用CLASS_NAME

wait(driver, 5).until(EC.visibility_of_element_located((By.CLASS_NAME, 'rankings-table')))

使用CSS_SELECTOR

wait(driver, 5).until(EC.visibility_of_element_located((By.CSS_SELECTOR, '.sc-ljMRFG.hgfcNB.rankings-table')))

【讨论】:

感谢您的回复,但恐怕没有用。我不恰当地使用id,但即使使用By.CLASS_NAME 也会导致相同的行为。它打开页面,在那里停留 5 秒钟,然后抛出一个错误。 @TrentFowler 你看到和以前一样的错误吗? 对不起,我错了。这似乎确实解决了这个问题。谢谢!

以上是关于如何使用 Selenium 等待页面上的元素可见(然后转到其他内容)?的主要内容,如果未能解决你的问题,请参考以下文章

selenium05-等待web元素的出现

Python Selenium 2 API 并等待 DOM 准备好/元素可见

Selenium - 页面更改后找不到元素,即使它是可见的

python selenium 三种等待方式详解

selenium-三种等待方式总结

等待多个元素变得不可见 Selenium Java