Selenium 不是尝试构建“网络爬虫”的最佳选择之一。有时它可能太不稳定,尤其是遇到意想不到的情况时。 Selenium WebDriver 是一个用于自动化和测试期望和用户交互的出色工具。
相反,良好的老式卷曲可能是网络爬行的更好选择。另外,我很确定有一些 ruby gem 可以帮助您进行网络爬行,只需 Google 搜索即可!
但要回答实际问题,如果您要使用 Selenium 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 查找的所有元素添加到您迭代的单个数组变量中。然后,当发生不好的事情时,需要进行一次救援(我假设您不想从那里自动退出,这就是为什么您只想将消息打印到屏幕上)。
学习干燥代码并使用外部 gem 将帮助您以更快的速度实现许多您想要做的事情。