使用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')
同样,该示例是返回页面,这可能会减慢您的速度。您可以将
get_response
替换为
request_head
,它会返回类似
get_response
的响应,这应该会有所帮助。 在任何一种情况下,你都需要考虑另一件事。许多站点使用“元刷新”,这会导致浏览器在解析页面后使用备用URL刷新页面。处理这些需要请求页面并解析它,寻找
<meta http-equiv="refresh" content="5" />
标签。 其他HTTP宝石如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(/[rn]+/).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
#<Typhoeus::Response:0x00000100ac3f68
 @app_connect_time=0.0,
 @body="",
 @code=302,
 @connect_time=0.055054,
 @curl_error_message="No error",
 @curl_return_code=0,
 @effective_url="http://www.example.com",
 @headers=
  "HTTP/1.0 302 FoundrnLocation: http://www.iana.org/domains/example/rnServer: BigIPrnConnection: Keep-AlivernContent-Length: 0rnrn",
 @http_version=nil,
 @mock=false,
 @name_lookup_time=0.001436,
 @pretransfer_time=0.055058,
 @request=
  :method => :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 <YOUR_LINKS_FILE_ONE_PER_LINE> | xargs curl --head --location -w '---HTTP_STATUS_CODE:%{http_code}nn' -s --retry 10 --globoff | grep HTTP_STATUS_CODE | cut -d: -f2 > <RESULTS_FILE>
值得注意的是,上述命令将遵循HTTP重定向,重试10次以查找临时错误(超时或5xx),当然只会获取标头。 更新:添加了--globoff,以便curl不会扩展任何url,如果它包含{}或[]     

要回复问题请先登录注册