为什么Selenium WebDriver在每次函数调用时都访问网络?

2 投票
3 回答
525 浏览
提问于 2025-04-18 12:17

我用Python写了一个简单的测试函数,使用了selenium webdriver:

from selenium import webdriver

def test_webdriver():
    web = webdriver.PhantomJS()
    web.get('http://example.com')
    web.find_element_by_tag_name('html')
    web.find_element_by_tag_name('head')
    web.find_element_by_tag_name('meta')
    web.find_element_by_tag_name('body')
    web.find_element_by_tag_name('title')
    web.find_element_by_tag_name('p')
    web.find_element_by_tag_name('div')

这个函数运行的时间比我预期的要长得多,所以我用cProfile来分析它,发现了一些这样的代码行:

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
      ...
        9    0.000    0.000    0.157    0.017 .../python2.7/urllib2.py:386(open)
      ...

这明显表明,webdriver在我的测试函数中每次调用find时都在访问网络。

我原以为webdriver只会在调用get()时抓取一次DOM,然后在本地搜索和操作,就像BeautifulSoup那样。显然,它并不是这样工作的,所以我有一些疑问:

  • 这是webdriver的正常行为,还是我配置错了?
  • 如果这确实是正常行为,有没有办法让webdriver在每次函数调用时访问网络?
  • 它访问网络是为了什么?每次find都刷新页面,这听起来不太合理。

注意:我知道测试页面上的JavaScript可能会触发意外的网络请求,所以我使用了http://example.com作为我的测试页面,以排除这种可能性。

3 个回答

-1

你会看到每次使用WebDriver时都有网络活动,因为WebDriver客户端就是通过这种方式和浏览器进行沟通的。

1

WebDriver 是一个比较底层的工具。你不想在这里实现通用的 DOM 缓存,因为 DOM 是不断变化的。相反,你应该在 WebDriver 之上构建一个框架,这样你就可以指定什么时候适合进行缓存。一个例子就是 Selenium-Java 项目中的 @CacheLookup 注解,它是 Page Factory 模式的一部分。

5

我认为,WebDriver和浏览器之间的通信是通过网络连接进行的:https://code.google.com/p/selenium/wiki/JsonWireProtocol

所以虽然它肯定不是对example.com发出九个请求,但它可能会向WebDriver发出九个本地网络请求。在你的例子中,这包括一个请求来启动浏览器,一个请求让浏览器执行GET操作,还有七个请求来查找页面中的元素。

应该有某种方法可以让你的WebDriver客户端库记录它实际向浏览器发出的调用。

撰写回答