首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Ruby中文本/csv内容编码= UTF-8的问题

Ruby中文本/csv内容编码= UTF-8的问题
EN

Stack Overflow用户
提问于 2013-09-15 00:04:22
回答 1查看 1.7K关注 0票数 1

当试图加载一个编码为UTF-8的CSV页面时,使用机械化V2.5.1,我使用了以下代码:

代码语言:javascript
复制
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'])

但是我发现内容编码钩子没有被调用,我得到了以下错误和回溯:

代码语言:javascript
复制
/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>'

有谁知道为什么内容钩子代码没有触发,为什么我会得到错误?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-09-15 02:12:52

但是我发现内容编码钩子没有被调用。

什么事情使你那样想?

错误消息引用以下代码:

代码语言:javascript
复制
  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的源代码包含以下内容:

代码语言:javascript
复制
  # 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

所以看起来你甚至不像是在召唤右钩。

下面是我要做的一个例子:

代码语言:javascript
复制
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:

代码语言:javascript
复制
#!/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: none
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/18807599

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档