- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我正在尝试编写一个爬虫,它从加载的页面中爬取所有链接,并将所有请求和响应 header 以及响应正文记录在某些文件中,比如 XML 或 txt。我在新浏览器窗口中打开第一个加载页面的所有链接,所以我不会收到此错误:
Element not found in the cache - perhaps the page has changed since it was looked up
我想知道从所有链接发出请求和接收响应然后从所有打开的窗口中定位输入元素和提交按钮的替代方法是什么。我可以在某种程度上做到以上几点,除非打开的窗口有公共(public)站点搜索框,就像这个 http://www.testfire.net 上的一个一样在右上角。我想做的是我想省略这样的公共(public)框,这样我就可以使用 webdriver 的 i.send_keys "value"
方法用值填充其他输入,并且不会出现此错误错误:在缓存中找不到元素 - 页面可能在查找后发生了变化。
从每个打开的窗口中检测和区分输入标签的方法是什么,以便在出现在大多数网站页面上的常见输入标签中不会重复填充值。我的代码如下:
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)
指导我如何使用 Selenium Webdriver 或使用 ruby 的 net/http
的 http.set_debug_output
获取所有带有响应主体的请求和响应 header ?
最佳答案
Selenium 不是用于尝试构建“网络爬虫”的最佳选择之一。有时它可能太古怪了,尤其是当它遇到意想不到的场景时。 Selenium WebDriver 是用于自动化和测试预期和用户交互的出色工具。相反,良好的老式 curl 可能是网络爬虫的更好选择。另外,我很确定有一些 ruby gem 可以帮助您进行网络抓取,只需 Google 搜索即可!
但是如果您要使用 Selenium WebDriver,则要回答实际问题:
我会制定一个过滤算法,您可以在其中将与您交互的元素的 HTML 添加到一个变量数组中。然后,当您转到下一个窗口/选项卡/链接时,它会检查变量数组并在找到匹配的 HTML 值时跳过该元素。
遗憾的是,SWD 不支持使用其 API 获取请求 header 和响应。常见的解决方法是使用第三方代理来拦截请求。
============
现在我想解决您的代码中的一些问题。
我建议在遍历链接之前,添加一个 @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 查找的所有元素添加到您迭代的单个数组变量中的。然后,当发生不好的事情时,需要一次救援(我假设您不想从那里自动退出,这就是为什么您只想将消息打印到屏幕上)。
学习干燥您的代码并使用外部 gem 将帮助您以更快的速度实现您想要做的很多事情。
关于ruby - 在缓存中找不到元素 - 也许页面在 Selenium Ruby 网络驱动程序中查找后发生了变化?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10732015/
例如,我有一个父类Author: class Author { String name static hasMany = [ fiction: Book,
代码如下: dojo.query(subNav.navClass).forEach(function(node, index, arr){ if(dojo.style(node, 'd
我有一个带有 Id 和姓名的学生表和一个带有 Id 和 friend Id 的 Friends 表。我想加入这两个表并找到学生的 friend 。 例如,Ashley 的 friend 是 Saman
我通过互联网浏览,但仍未找到问题的答案。应该很容易: class Parent { String name Child child } 当我有一个 child 对象时,如何获得它的 paren
我正在尝试创建一个以 Firebase 作为我的后端的社交应用。现在我正面临如何(在哪里?)找到 friend 功能的问题。 我有每个用户的邮件地址。 我可以访问用户的电话也预订。 在传统的后端中,我
我主要想澄清以下几点: 1。有人告诉我,在 iOS 5 及以下版本中,如果您使用 Game Center 设置多人游戏,则“查找 Facebook 好友”(如与好友争夺战)的功能不是内置的,因此您需要
关于redis docker镜像ENTRYPOINT脚本 docker-entrypoint.sh : #!/bin/sh set -e # first arg is `-f` or `--some-
我是一名优秀的程序员,十分优秀!