繁体   English   中英

Ruby NET::HTTP 在正文之前读取标题(没有 HEAD 请求)?

[英]Ruby NET::HTTP Read the header BEFORE the body (without HEAD request)?

我正在使用 Net::HTTP 和 Ruby 来抓取 URL。

我不想抓取流式音频,例如: http : //listen2.openstream.co/334

实际上我只想抓取 Html 内容,所以没有 pdf、视频、txt ..

现在,我将 open_timeout 和 read_timeout 都设置为 10,因此即使我确实抓取了这些流音频页面,它们也会超时。

url = 'http://listen2.openstream.co/334'
path = uri.path

req= Net::HTTP::Get.new(path, {'Accept' => '*/*', 'Content-Type' => 'text/plain; charset=utf-8', 'Connection' => 'keep-alive','Accept-Encoding' => 'Identity'})

uri = Addressable::URI.parse(url)   

resp =  Net::HTTP.start(uri.host, uri.inferred_port) do |httpRequest|
    httpRequest.open_timeout = 10
    httpRequest.read_timeout = 10
    #how can I read the headers here before it's streaming the body and then exit b/c the content type is audio?
    httpRequest.request(req)
end

但是,在我阅读 http 响应的正文以查看它是否是音频之前,有没有办法检查标头? 我想这样做而不发送单独的 HEAD 请求。

net/http支持流式传输,您可以使用它来读取正文之前的标题。

代码示例,

url = URI('http://stackoverflow.com/questions/41306082/ruby-nethttp-read-the-header-before-the-body-without-head-request')

Net::HTTP.start(url.host, url.port) do |http|
  request = Net::HTTP::Get.new(url)
  http.request(request) do |response|

    # check headers here, body has not yet been read
    # then call read_body or just body to read the body

    if true  
      response.read_body do |chunk|
        # process body chunks here
      end
    end
  end
end

我将在今晚晚些时候添加一个 ruby​​ 示例。 但是,为了快速响应。 有一个简单的技巧可以做到这一点。

您可以使用 HTTP Range标头来指示您是否希望从服务器接收的字节范围。 下面是一个例子:

curl -XGET http://www.sample-videos.com/audio/mp3/crowd-cheering.mp3 -v -H "Range: bytes=0-1"

上面的例子意味着服务器将返回 0 到 1 字节范围的数据。

请参阅: https : //developer.mozilla.org/en-US/docs/Web/HTTP/Range_requests

由于我没有找到在 Net::HTTP 中正确执行此操作的方法,并且我看到您已经在使用addressable gem 作为外部依赖项,因此这里有一个使用美妙的http gem的解决方案:

require 'http'

response = HTTP.get('http://listen2.openstream.co/334')
# Here are the headers
puts response.headers

# Everything ok? Start streaming the response
body = response.body
body.stream!

# now just call `readpartial` on the body until it returns `nil`
# or some other break condition is met

抱歉,如果您需要使用 Net::HTTP,希望其他人能找到答案。 在这种情况下,单独的HEAD请求可能确实是HEAD的方法。

您可以在不使用 gem 的情况下完成大量与网络相关的事情。 只需使用net/http模块。

require 'net/http'

url = URI 'http://listen2.openstream.co/334'

Net::HTTP.start(url.host, url.port){|conn|
  conn.request_get(url){|resp|
    resp.each{|k_header, v_header|
      # process headers
      puts "#{k_header}: #{v_header}"
    }
    #
    # resp.read_body{|body_chunk|
    #   # process body
    # }
  }
}

注意:在处理标题时,只需确保检查content-type标题。 对于音频相关内容,它通常包含audio/mpeg值。

希望,它有帮助。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM