【问题标题】:How to get Mechanize to auto-convert body to UTF8?如何让 Mechanize 将正文自动转换为 UTF8?
【发布时间】:2012-02-10 11:28:42
【问题描述】:

我找到了一些使用post_connect_hookpre_connect_hook 的解决方案,但似乎它们不起作用。我正在使用最新的 Mechanize 版本(2.1)。新版没有[:response]字段,新版不知道在哪里找。

是否可以让 Mechanize 返回一个 UTF8 编码的版本,而不必使用 iconv 手动转换它?

【问题讨论】:

  • iconv 将在 ruby​​ 1.9 版本中被弃用。看看 String.froce_encoding
  • Mechanize 将编码更改回 ASCII-8BIT,即使我处处设置为 encoding,force_encoding,encode'ed string in encoding mechanize hook。一切都一样。我想我需要破解标题和 html 的元字符集。
  • 感谢您的提示。在底部我已经解释了一个新的encode 方法。
  • 您的 gist 链接不再有效。
  • @zhon 已修复。如果您可以提供更多信息,请查看。

标签: ruby utf-8 mechanize


【解决方案1】:

自 Mechanize 2.0 以来,pre_connect_hooks()post_connect_hooks() 的参数已更改。

请参阅Mechanize 文档:

pre_connect_hooks()

在检索响应之前要调用的挂钩列表。使用代理、URI、响应和响应正文调用挂钩。

 

post_connect_hooks()

检索响应后要调用的挂钩列表。使用代理、URI、响应和响应正文调用挂钩。

现在您无法更改内部响应主体值,因为参数不是数组。因此,下一个最好的方法是用您自己的替换内部解析器:

class MyParser
  def self.parse(thing, url = nil, encoding = nil, options = Nokogiri::XML::ParseOptions::DEFAULT_HTML, &block)
    # insert your conversion code here. For example:
    # thing = NKF.nkf("-wm0X", thing).sub(/Shift_JIS/,"utf-8") # you need to rewrite content charset if it exists.
    Nokogiri::HTML::Document.parse(thing, url, encoding, options, &block)
  end
end

agent = Mechanize.new
agent.html_parser = MyParser
page = agent.get('http://somewhere.com/')
...

【讨论】:

    【解决方案2】:

    我找到了一个效果很好的解决方案:

    class HtmlParser
      def self.parse(body, url, encoding)
        body.encode!('UTF-8', encoding, invalid: :replace, undef: :replace, replace: '')
        Nokogiri::HTML::Document.parse(body, url, 'UTF-8')
      end
    end
    
    Mechanize.new.tap do |web|
      web.html_parser = HtmlParser
    end
    

    尚未发现任何问题。

    【讨论】:

      【解决方案3】:

      在您的脚本中,只需输入:page.encoding = 'utf-8'

      但是,根据您的情况,您可能需要输入相反的内容(Mechanize 正在使用的网站的编码)。为此,打开 Firefox,打开您希望 Mechanize 使用的网站,在菜单栏中选择工具,然后打开页面信息。从那里确定页面的编码内容。

      使用该信息,您可以输入页面的编码内容(例如page.encoding = 'windows-1252')。

      【讨论】:

        【解决方案4】:

        这样的事情怎么样:

        class Mechanize
            alias_method :original_get, :get
            def get *args
                doc = original_get *args
                doc.encoding = 'utf-8'
                doc
            end
        end
        

        【讨论】:

        • 不起作用。仍然得到 '\r\n\r\n\xCD\xE5\xE4'
        • 我同意,最好编写一个调用@agent.get 并进行转换的get 方法。不过,您的问题似乎要求提供猴子补丁。
        • Monkeypatch 太丑了,这个功能应该在 mechanize 里面。 gist.github.com/480277 - 或多或少做了我需要的事情,但我不能使用content_encoding_hooks 做同样的事情,因为在 Page 类的机械化内部有一些代码可以将编码转换为 ASCII-8BIT,然后不可能将其返回到 WINDOWS-1251 并转换为 UTF-8。所以如果你能用content_encoding_hooks写代码,请更新你的记录,我会给你+50,这个问题将被标记为已回答。谢谢。
        猜你喜欢
        • 2013-10-22
        • 1970-01-01
        • 2012-03-21
        • 2017-02-24
        • 1970-01-01
        • 2021-11-14
        • 1970-01-01
        • 2015-09-24
        • 2019-12-21
        相关资源
        最近更新 更多