使用Watir检查错误的链接

我有一个无序的链接列表,我保存到一边,我想点击每个链接,并确保它进入一个真实的页面,并没有404,500等。

问题是我不知道该怎么做。 是否有一些我可以检查的对象会给我http状态代码或什么?

mylinks = Browser.ul(:id, 'my_ul_id').links mylinks.each do |link| link.click # need to check for a 200 status or something here! how? Browser.back end 

我的答案与Tin Man相似。

要求'net / http'
要求'uri'

 mylinks = Browser.ul(:id,'my_ul_id')。链接

 mylinks.each做|链接|
   u = URI.parse link.href
   status_code = Net :: HTTP.start(u.host,u.port){| http |  http.head(u.request_uri).code}
  使用rspec进行测试
   status_code.should =='200'
结束

如果你使用Test :: Unit来测试框架,我认为你可以测试如下

   assert_equal'200',status_code

另一个样本(包括Chuck van der Linden的想法):如果状态不好,请检查状态代码并注销URL。

要求'net / http'
要求'uri'

 mylinks = Browser.ul(:id,'my_ul_id')。链接

 mylinks.each做|链接|
   u = URI.parse link.href
   status_code = Net :: HTTP.start(u.host,u.port){| http |  http.head(u.request_uri).code}
  除非status_code =='200'
     File.open( 'error_log.txt', 'A +'){|文件|  file.puts“#{link.href}是#{status_code}”}
  结束
结束

没有必要为此使用Watir。 HTTP HEAD请求将让您了解URL是否解析并且速度更快。

Ruby的Net::HTTP可以做到,或者你可以使用Open::URI

使用Open :: URI,您可以请求URI,然后返回页面。 因为您并不真正关心页面包含的内容,所以您可以丢弃该部分,只返回是否有内容:

 require 'open-uri' if (open('http://www.example.com').read.any?) puts "is" else puts "isn't" end 

好处是Open :: URI解决了HTTP重定向问题。 缺点是它返回整页,所以它可能很慢。

Ruby的Net :: HTTP可以有所帮助,因为它可以使用HTTP HEAD请求,它不返回整个页面,只返回标题。 这本身并不足以知道实际页面是否可以访问,因为HEAD响应可能会重定向到无法解析的页面,因此您必须循环重定向,直到您没有获得重定向,或者您得到一个错误。 Net :: HTTP文档有一个示例可以帮助您入门:

 require 'net/http' require 'uri' def fetch(uri_str, limit = 10) # You should choose better exception. raise ArgumentError, 'HTTP redirect too deep' if limit == 0 response = Net::HTTP.get_response(URI.parse(uri_str)) case response when Net::HTTPSuccess then response when Net::HTTPRedirection then fetch(response['location'], limit - 1) else response.error! end end print fetch('http://www.ruby-lang.org') 

同样,该示例是返回页面,这可能会减慢您的速度。 你可以用request_head替换get_response ,它返回一个像get_response那样的响应,这应该会有所帮助。

在任何一种情况下,你都需要考虑另一件事。 许多站点使用“ 元刷新 ”,这会导致浏览器在解析页面后使用备用URL刷新页面。 处理这些需要请求页面并解析它,寻找标签。

其他HTTPgem如Typhoeus和Patron也可以轻松地进行HEAD请求,所以也要看看它们。 特别是,Typhoeus可以通过其配套的Hydra处理一些重负荷,让您轻松使用并行请求。


编辑:

 require 'typhoeus' response = Typhoeus::Request.head("http://www.example.com") response.code # => 302 case response.code when (200 .. 299) # when (300 .. 399) headers = Hash[*response.headers.split(/[\r\n]+/).map{ |h| h.split(' ', 2) }.flatten] puts "Redirected to: #{ headers['Location:'] }" when (400 .. 499) # when (500 .. 599) # end # >> Redirected to: http://www.iana.org/domains/example/ 

如果你没有玩过一个,这就是响应的样子。 它对于你所看到的那种情况非常有用:

 (rdb:1) pp response # :head, :url => http://www.example.com, :headers => {"User-Agent"=>"Typhoeus - http://github.com/dbalatero/typhoeus/tree/master"}, @requested_http_method=nil, @requested_url=nil, @start_time=nil, @start_transfer_time=0.109741, @status_message=nil, @time=0.109822> 

如果您要检查很多URL,请参阅Typhoeus中的Hydra示例 。

关于watir或watir-webdriver是否应提供HTTP返回码信息,存在一些哲学争论。 前提是Watir在DOM上模拟的普通“用户”不知道HTTP返回码。 我不一定同意这一点,因为我对主要(性能测试等)的用例略有不同……但它就是它的本质。 这个主题表达了对这种区别的一些看法=> http://groups.google.com/group/watir-general/browse_thread/thread/26486904e89340b7

目前没有简单的方法来确定来自Watir的HTTP响应代码而不使用代理/ Fiddler / HTTPWatch / TCPdump等补充工具,或者降级到测试中的脚本的net / http级别…我个人喜欢使用带有netexport插件的firebug回顾一下测试。

如果你有大量的链接,所有以前的解决方案效率都很低,因为对于每个链接,它将与托管链接的服务器建立新的HTTP连接。

我编写了一个单行bash命令,它将使用curl命令获取stdin提供的链接列表,并返回与每个链接对应的状态代码列表。 这里的关键点是curl在同一个调用中获取所有链接,它将重用 HTTP连接,这将显着提高速度。

但是,curl会将列表分成256块,这仍然远远超过1块! 要确保重用连接,请先对链接进行排序(只需使用sort命令)。

 cat  | xargs curl --head --location -w '---HTTP_STATUS_CODE:%{http_code}\n\n' -s --retry 10 --globoff | grep HTTP_STATUS_CODE | cut -d: -f2 >  

值得注意的是,上述命令将遵循HTTP重定向,对于临时错误(超时或5xx)重试10次,当然只会获取标头。

更新:添加–globoff,以便curl不会扩展任何url,如果它包含{}或[]