Selenium 点击链接只成功一次,再次调用 click() 返回错误

3 投票
2 回答
2459 浏览
提问于 2025-04-17 23:37

我刚接触Selenium,写了这些代码。我想通过点击右下角的'>'链接来抓取表格中的数据。第一次点击可以,但接下来的两次点击却不行。我漏掉了什么呢?谢谢。

# coding: utf-8
from selenium import webdriver
from selenium.webdriver.common.by import By

browser = webdriver.Firefox()
browser.get('http://s.cafef.vn/Lich-su-giao-dich-HSG-1.chn')

next_page_link = browser.find_element_by_partial_link_text('>')
next_page_link.click()
next_page_link = browser.find_element_by_partial_link_text('>')
next_page_link.click()
next_page_link = browser.find_element_by_partial_link_text('>')
next_page_link.click()

这里是出现的异常

Traceback (most recent call last):
  File "cafef.py", line 13, in <module>
    next_page_link.click()
  File "/usr/local/lib/python2.7/dist-packages/selenium-2.40.0-py2.7.egg/selenium/webdriver/remote/webelement.py", line 59, in click
    self._execute(Command.CLICK_ELEMENT)
  File "/usr/local/lib/python2.7/dist-packages/selenium-2.40.0-py2.7.egg/selenium/webdriver/remote/webelement.py", line 369, in _execute
    return self._parent.execute(command, params)
  File "/usr/local/lib/python2.7/dist-packages/selenium-2.40.0-py2.7.egg/selenium/webdriver/remote/webdriver.py", line 164, in execute
    self.error_handler.check_response(response)
  File "/usr/local/lib/python2.7/dist-packages/selenium-2.40.0-py2.7.egg/selenium/webdriver/remote/errorhandler.py", line 164, in check_response
    raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.StaleElementReferenceException: Message: u'Element is no longer attached to the DOM' ; Stacktrace: 
    at fxdriver.cache.getElementAt (resource://fxdriver/modules/web_element_cache.js:7613)
    at Utils.getElementAt (file:///tmp/tmpIDOSdW/extensions/fxdriver@googlecode.com/components/command_processor.js:7210)
    at fxdriver.preconditions.visible (file:///tmp/tmpIDOSdW/extensions/fxdriver@googlecode.com/components/command_processor.js:8223)
    at DelayedCommand.prototype.checkPreconditions_ (file:///tmp/tmpIDOSdW/extensions/fxdriver@googlecode.com/components/command_processor.js:10861)
    at DelayedCommand.prototype.executeInternal_/h (file:///tmp/tmpIDOSdW/extensions/fxdriver@googlecode.com/components/command_processor.js:10878)
    at DelayedCommand.prototype.executeInternal_ (file:///tmp/tmpIDOSdW/extensions/fxdriver@googlecode.com/components/command_processor.js:10883)
    at DelayedCommand.prototype.execute/< (file:///tmp/tmpIDOSdW/extensions/fxdriver@googlecode.com/components/command_processor.js:10825) 

2 个回答

1

通常,unutbu 的回答就足够了。

我用的是 .net 的 selenium,而不是 python,所以不能给你详细的 python 代码。不过为了让程序更稳定,你应该等三次:

  1. 等下一页或者 ajax 内容加载完成。在这种情况下,你要等到 .CafeF_Paging td span strong 里的文字变成你期待的页码。
  2. 等 jQuery 加载完成,直到 jQuery.active 等于 0。
    你可以查看这个链接了解更多:http://sullerton.com/2013/08/selenium-webdriver-wait-for-ajax-with-python/
  3. 等元素可见,而不仅仅是找到它,使用 visibility_of_element_located。
4

第二次调用 next_page_link.click() 的时候,浏览器还没有加载完下一页。你需要加一个 等待,确保页面加载完成后再点击,使用 EC.element_to_be_clickable 来检查元素是否可以点击:

from selenium import webdriver
import selenium.webdriver.support.ui as UI
from selenium.webdriver.common.by import By
import selenium.webdriver.support.expected_conditions as EC 
import contextlib

with contextlib.closing(webdriver.Firefox()) as browser:
    browser.get('http://s.cafef.vn/Lich-su-giao-dich-HSG-1.chn')
    wait = UI.WebDriverWait(browser, 10)
    for i in range(3):            
        next_page_link = wait.until(
            EC.element_to_be_clickable((By.PARTIAL_LINK_TEXT, '>')))
        next_page_link.click()

撰写回答