Android/ Jsoup:如何解决编码问题

Android/ Jsoup: how to fix encoding issues

我正在开发一个应用程序来获取在线立法并自动解析和格式化它以适合该应用程序。我使用的测试站点是

http://www.planalto.gov.br/ccivil_03/constituicao/constituicao.htm

我想获取 URL 的所有内容,解析(可能清理)它们并将它们放入文件中。我正在使用 Jsoup,这是我用来连接并将内容打印到文件的 Runnable:

class FetchHtmlRunnable implements Runnable {
        String url;

        FetchHtmlRunnable(String url) {
            this.url = url;
        }

        @Override
        public void run() {
            try {
                Document doc = Jsoup.parse(new URL(url), 10000);
                doc.charset(Charset.forName("windows-1252"));
                Charset charset = doc.charset();

                String htmlString = Jsoup.clean(doc.toString(), new Whitelist());

                Log.d(TAG, "run: HTMLSTRING: " + htmlString);

                String root = context.getFilesDir().toString();
                file = new File(root + File.separator + "law.txt");

                OutputStreamWriter out = new OutputStreamWriter(new FileOutputStream(file, false), charset);
                out.write(htmlString);
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
    }

然而,即使 Chrome 告诉我网站的编码是 windows-1252,日志条目和文件不仅充满了替换字符(它丢失了所有带有变音符号的字符,例如 í 和 ã),它也会丢失所有新行:

Constitui��o Presid�ncia da Rep�blica Casa Civil Subchefia para Assuntos Jur�dicos CONSTITUI��O DA REP�BLICA FEDERATIVA DO BRASIL DE 1988 Vide Emenda Constitucional n� 91, de 2016 Vide Emenda Constitucional n� 106, de 2020 Vide Emenda Constitucional n� 107, de 2020 Emendas Constitucionais Emendas Constitucionais de Revis�o Ato das Disposi��es Constitucionais Transit�rias Atos decorrentes do disposto no � 3� do art. 5� �NDICE TEM�TICO Texto compilado PRE�MBULO N�s, representantes do povo brasileiro, reunidos em Assembl�ia Nacional Constituinte para instituir um Estado Democr�tico, destinado a assegurar o exerc�cio dos direitos sociais e individuais, a liberdade, a seguran�a, o bem-estar, o desenvolvimento, a igualdade e a justi�a como valores supremos de uma sociedade fraterna, pluralista e sem preconceitos, fundada na harmonia social e comprometida

也许更擅长网络开发的人可以告诉我这是否是网页本身的问题以及我如何解决这个问题...以及如何保留换行符。

我将在一秒钟内用葡萄牙语、西班牙语(和中文)写下这个关于字符集的答案的其余部分......不过,首先,让我说你正在尝试阅读的页面 - 实际上加载了页面内容使用 "AJAX / JS"。我可以使用我自己在 Internet 上可用的库下载 AJAX,但是 SeleniumPuppeteerSplash 等其他工具会有必要。不提字符集,您如何首先将“巴西宪法”的内容下载到 HTML?当我尝试直接 HTML 下载器(不执行脚本)时,我得到一堆 Java-Script 根本没有任何葡萄牙语 - 它看起来一点也不像 HTML posted在你的问题中。 :)

如果您已经在下载 HTML,并且只是字符集有问题,请阅读下面的答案。如果您无法下载除 AJAX / Java 脚本调用之外的任何内容 - 我可以 post 另一个解释执行 JS / AJAX 的答案不同的答案。 (本质上,您 posted 与我得到的输出不同)。


在99.9999%的情况下,如果不是直线上升"ASCII"(因为它有外文字符),那么(几乎)保证使用 "UTF-8" Character-Set 的版本可读。我翻译西班牙新闻文章和中文新闻文章 - UTF-8 总是适合我。我有一个西班牙网站需要一种名为 "iso8859-1" 的编码,但除了我发现它的“Don Quijote de La Mancha”网站之外 - UTF8 有效。

说实话,这根本不是问题,因为当 阅读 web-page(相对于写一个),Java 自动将文本解析为 UTF-8,无需任何配置。这是我写的库中的“打开连接”方法体:

HttpURLConnection con =                     (HttpURLConnection) url.openConnection();
con.setRequestMethod                        ("GET");
if (USE_USER_AGENT) con.setRequestProperty  ("User-Agent", USER_AGENT);
return new BufferedReader                   (new InputStreamReader(con.getInputStream()));

这是我的库中“抓取内容”方法的方法体:

URL url = new URL("http://www.planalto.gov.br/ccivil_03/constituicao/constituicao.htm");
StringBuilder sb = new StringBuilder();
String s;
BufferedReader br = Scrape.openConn(url);
while ((s = br.readLine()) != null) sb.append(s + "\n");
FileRW.writeFile(sb.toString(), "page.html");

老实说,我对 Microsoft 字符集一无所知。我在 UNIX 中编写代码,我从不担心任何字符集 - 除了确保 在编写 HTML 时(与 Reading HTML)相反,HTML <META CHARSET="utf-8"> 元素被插入到我的页面中.