在缓存中找不到元素 - 也许是页面已经改变,因为它在硒Ruby网络驱动抬头?(Element not

2019-09-17 10:55发布

我想写的是抓取从加载的页面所有链接,并记录所有请求和响应头,在一些文件响应身体沿说,XML或TXT履带。 我打开在新的浏览器窗口中第一次加载页面的所有链接,所以我不会得到这个错误:

Element not found in the cache - perhaps the page has changed since it was looked up

我想知道什么可以替代的方式来发出请求和接收的所有环节响应,然后找到输入元素,并提交按钮,形成所有打开的窗口。 我能上面做一定程度的时候,除了打开的窗口中有常见的部位searh像一个在此框http://www.testfire.net在右上角。 我想要做的就是我想省略这种共同的框,以便我可以使用填充值其他输入i.send_keys "value"的webdriver的方法,并没有得到这个错误ERROR:元素在缓存中没有发现-也许是页面有更改,因为它被抬起头来。

什么是检测和区分输入标签从每个打开的窗口,使价值没有得到重复的出现在网站的最常见的网页输入标签填充的方式。 我的代码如下:

require 'rubygems'
require 'selenium-webdriver'
require 'timeout'

class Clicker
def open_new_window(url)
  @driver = Selenium::WebDriver.for :firefox
  @url = @driver.get " http://test.acunetix.com "
  @link = Array.new(@driver.find_elements(:tag_name, "a"))
  @windows = Array.new(@driver.window_handles())
  @link.each do |a|
      a = @driver.execute_script("var d=document,a=d.createElement('a');a.target='_blank';a.href=arguments[0];a.innerHTML='.';d.body.appendChild(a);return a", a)
      a.click
    end
    i = @driver.window_handles
    i[0..i.length].each do |handle|
        @driver.switch_to().window(handle)
        puts @driver.current_url()
        inputs = Array.new(@driver.find_elements(:tag_name, 'input'))
        forms = Array.new(@driver.find_elements(:tag_name, 'form'))
        inputs.each do |i|
            begin
                i.send_keys "value"
                puts i.class
                i.submit
                rescue Timeout::Error => exc
                    puts "ERROR: #{exc.message}"
                rescue Errno::ETIMEDOUT => exc
                    puts "ERROR: #{exc.message}"
                rescue Exception => exc
                    puts "ERROR: #{exc.message}"
            end
        end 
        forms.each do |j|
            begin
                j.send_keys "value"
                j.submit
                rescue Timeout::Error => exc
                    puts "ERROR: #{exc.message}"
                rescue Errno::ETIMEDOUT => exc
                    puts "ERROR: #{exc.message}"
                rescue Exception => exc
                    puts "ERROR: #{exc.message}"
            end
        end

    end
#Switch back to the original window
    @driver.switch_to().window(i[0])
end
end
ol = Clicker.new
url = ""
ol.open_new_window(url)

指导我怎样才能得到使用硒的webdriver或使用与响应主体所有requeat和响应头http.set_debug_output红宝石的的net/http

Answer 1:

硒是不是用来试图建立一个“网络爬虫”的最佳选择之一。 它有时可能太古怪,特别是当它遇到意想不到的情况。 硒的webdriver是自动化和测试的预期和用户交互的一个很好的工具。 相反,良好的老式卷发很可能是网络爬行一个更好的选择。 此外,我敢肯定有一些红宝石的宝石,可以帮助你的网络抓取,只是谷歌搜索吧!

但要回答这个问题,实际如果你使用硒的webdriver:

我工作的滤波算法,其中可以添加你到一个变量数组交互元素的HTML。 然后,当你去到下一个窗口/标签/链接,它会检查对变量数组并跳过元素,如果找到匹配的HTML值。

不幸的是,SWD不支持获取请求头和响应与它的API。 常见的解决办法是使用第三方代理拦截请求。

============

现在,我想解决你的代码的几个问题。

我会遍历链接之前建议,添加一个@default_current_window = @driver.window_handle 。 这将允许你总是在当你调用脚本的末尾回返回到正确的窗口@driver.switch_to.window(@default_current_window)

在你@links迭代器,而不是遍历所有可以显示,使用尽可能窗口@driver.switch_to.window(@driver.window_handles.last) 这将切换到最近显示的新窗口(和它仅需要每链接点击一次发生!)。

你可以做这样的事情干起来你的投入和表单代码:

inputs = []
inputs << @driver.find_elements(:tag_name => "input")
inputs << @driver.find_elements(:tag_name => "form")
inputs.flatten
inputs.each do |i|
  begin
    i.send_keys "value"
    i.submit
  rescue e
    puts "ERROR: #{e.message}"
  end
end

请注意,我怎么刚才添加所有你想要的SWD寻找到您遍历一个数组变量的元素。 然后,当坏事发生,需要一个单一的救援(我假设你不希望从那里自动退出,这就是为什么你只是要打印的消息到屏幕)。

学习干涸你的代码,并使用外部的宝石将帮助你实现很多你正在尝试做的,并以更快的速度。



文章来源: Element not found in the cache - perhaps the page has changed since it was looked up in Selenium Ruby web driver?