如何使用 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 等待页面上的元素可见(然后转到其他内容)?的主要内容,如果未能解决你的问题,请参考以下文章