当试图加载一个编码为UTF-8的CSV页面时,使用机械化V2.5.1,我使用了以下代码:
a.content_encoding_hooks << lambda{|httpagent, uri, response, body_io|
response['Content-Encoding'] = 'none' if response['Content-Encoding'].to_s == 'UTF-8'
}
p4 = a.get(redirect_url, nil, ['accept-encoding' => 'UTF-8'])但是我发现内容编码钩子没有被调用,我得到了以下错误和回溯:
/Users/jackrg/.rbenv/versions/1.9.2-p290/lib/ruby/gems/1.9.1/gems/mechanize-2.5.1/lib/mechanize/http/agent.rb:787:in 'response_content_encoding': unsupported content-encoding: UTF-8 (Mechanize::Error)
from /Users/jackrg/.rbenv/versions/1.9.2-p290/lib/ruby/gems/1.9.1/gems/mechanize-2.5.1/lib/mechanize/http/agent.rb:274:in 'fetch'
from /Users/jackrg/.rbenv/versions/1.9.2-p290/lib/ruby/gems/1.9.1/gems/mechanize-2.5.1/lib/mechanize/http/agent.rb:949:in 'response_redirect'
from /Users/jackrg/.rbenv/versions/1.9.2-p290/lib/ruby/gems/1.9.1/gems/mechanize-2.5.1/lib/mechanize/http/agent.rb:299:in 'fetch'
from /Users/jackrg/.rbenv/versions/1.9.2-p290/lib/ruby/gems/1.9.1/gems/mechanize-2.5.1/lib/mechanize/http/agent.rb:949:in 'response_redirect'
from /Users/jackrg/.rbenv/versions/1.9.2-p290/lib/ruby/gems/1.9.1/gems/mechanize-2.5.1/lib/mechanize/http/agent.rb:299:in 'fetch'
from /Users/jackrg/.rbenv/versions/1.9.2-p290/lib/ruby/gems/1.9.1/gems/mechanize-2.5.1/lib/mechanize.rb:407:in 'get'
from prototype/test1.rb:307:in `<main>'有谁知道为什么内容钩子代码没有触发,为什么我会得到错误?
发布于 2013-09-15 02:12:52
但是我发现内容编码钩子没有被调用。
什么事情使你那样想?
错误消息引用以下代码:
def response_content_encoding response, body_io
...
...
out_io = case response['Content-Encoding']
when nil, 'none', '7bit', "" then
body_io
when 'deflate' then
content_encoding_inflate body_io
when 'gzip', 'x-gzip' then
content_encoding_gunzip body_io
else
raise Mechanize::Error,
"unsupported content-encoding: #{response['Content-Encoding']}"因此,机械只识别内容编码:'7bit','deflate','gzip',或‘x’。
来自HTTP/1.1规范:
4.11内容-编码 内容编码实体-标头字段用作媒体类型的修饰符.当它出现时,它的值表示对实体体应用了哪些附加的内容编码,因此必须应用什么解码机制才能获得内容类型标头字段引用的媒体类型。内容-编码主要用于允许压缩文档而不丢失其底层媒体类型的标识。 内容-编码=“内容-编码":”1#内容-编码 内容编码在第3.5节中定义。其使用的一个例子是 内容-编码: gzip 内容编码是请求URI标识的实体的一个特征。通常,实体体与此编码一起存储,并且只在呈现或类似使用之前被解码。但是,如果新编码为收件人所接受,则非透明代理可以修改内容编码,除非消息中存在“不转换”缓存控制指令。 ... 3.5内容编码 内容编码值表示已经或可以应用于实体的编码转换。内容编码主要用于允许对文档进行压缩、或其他有用的转换,而不会丢失其底层媒体类型的标识,并且不会丢失信息。通常情况下,实体以编码形式存储,直接传输,并且只由接收方解码。 内容编码=令牌 所有内容编码值都不区分大小写。HTTP/1.1在接受编码(第14.3节)和内容编码(第14.11节)标题字段中使用内容编码值.尽管该值描述了内容编码,但更重要的是它表明了删除编码所需的解码机制。 因特网分配数字管理机构(IANA)充当内容编码值令牌的注册中心.最初,注册表包含以下令牌: gzip是由文件压缩程序"gzip“(Gzip)生成的编码格式,如RFC 1952年25所述。这种格式是一个32位CRC的Lempel-Ziv编码(LZ77) . 压缩通用文件压缩程序“压缩”产生的编码格式。这种格式是一种自适应的Lempel-Ziv-Welch编码(LZW). 使用程序名称标识编码格式是不可取的,今后的编码也不鼓励使用。它们在这里的使用是历史实践的代表,不是很好的设计。为了与以前的HTTP实现兼容,应用程序应该考虑"x-gzip“和”x-压缩“分别等同于"gzip”和"compress“。 将RFC 1950 31中定义的"zlib“格式与RFC 1951 29中描述的”平减“压缩机制结合起来。 identity默认(标识)编码;不使用任何转换。此内容编码仅在接受编码头中使用,不应在内容编码标头中使用. http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.5
换句话说,http内容编码与ascii诉utf-8诉拉丁文-1无关。
此外,机器化::HTTP::Agent的源代码包含以下内容:
# A list of hooks to call after retrieving a response. Hooks are called with
# the agent and the response returned.
attr_reader :post_connect_hooks
# A list of hooks to call before making a request. Hooks are called with
# the agent and the request to be performed.
attr_reader :pre_connect_hooks
# A list of hooks to call to handle the content-encoding of a request.
attr_reader :content_encoding_hooks所以看起来你甚至不像是在召唤右钩。
下面是我要做的一个例子:
require 'mechanize'
a = Mechanize.new
p a.content_encoding_hooks
func = lambda do |a, uri, resp, body_io|
puts body_io.read
puts "The Content-Encoding is: #{resp['Content-Encoding']}"
if resp['Content-Encoding'].to_s == 'UTF-8'
resp['Content-Encoding'] = 'none'
end
puts "The Content-Encoding is now: #{resp['Content-Encoding']}"
end
a.content_encoding_hooks << func
a.get(
'http://localhost:8080/cgi-bin/myprog.rb',
[],
nil,
"Accept-Encoding" => 'gzip, deflate' #This is what Firefox always uses
)myprog.rb:
#!/usr/bin/env ruby
require 'cgi'
cgi = CGI.new('html3')
headers = {
"type" => 'text/html',
"Content-Encoding" => "UTF-8",
}
cgi.out(headers) do
cgi.html() do
cgi.head{ cgi.title{"Content-Encoding Test"} } +
cgi.body() do
cgi.div(){ "The Accept-Encoding was: #{cgi.accept_encoding}" }
end
end
end
--output:--
[]
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"><HTML><HEAD><TITLE>Content-Encoding Test</TITLE></HEAD><BODY><DIV>The Accept-Encoding was: gzip, deflate</DIV></BODY></HTML>
The Content-Encoding is: UTF-8
The Content-Encoding is now: nonehttps://stackoverflow.com/questions/18807599
复制相似问题