【问题标题】:Read and download a page's source as Unicode in Java在 Java 中以 Unicode 格式读取和下载页面的源代码
【发布时间】:2013-07-16 05:23:00
【问题描述】:

现在,我有一些代码可以读取页面并将所有内容保存到 html 文件中。但是,有一些问题...一些标点符号和特殊字符显示为问号。

当然,如果我手动执行此操作,我会使用 Unicode 编码而不是默认的 ANSI 保存 .txt 文件。我环顾四周,我所看到的只是抱怨 Java 不可能或我不理解的一半解释......

无论如何,谁能帮我改正问号?这是我下载页面的代码部分。 (lister 创建一个 url 数组来下载,用于有页面的网站。你可以忽略它,它工作正常。)

public void URLDownloader(String site, int startPage, int endPage) throws Exception {
String[] pages = URLLister(site, startPage, endPage);
String webPage = pages[0];
int fileNumber = startPage;
if (startPage == 0)
  fileNumber++;

//change pages
for(int i = 0; i < pages.length; i++) {
  webPage = pages[i]; 
  URL url= new URL(webPage);
  BufferedReader in = new BufferedReader( 
                                         new InputStreamReader(url.openStream()));
  PrintWriter out = new PrintWriter(name + (fileNumber+i) + ".html");
  String inputLine;


  //while stuff to read on current page
  while ((inputLine = in.readLine()) != null) {
    out.println(inputLine); //write line of text
  }
  out.close();    //end writing text
  if (startPage == 0)
    startPage++;
  console.append("Finished page " + startPage + "\n");
  startPage++;
}      

【问题讨论】:

  • 这是什么语言?爪哇?
  • 哎呀,对不起。是的,它是 Java。修改了标题。
  • 更好 - 我添加了java 标签。

标签: java html encoding unicode


【解决方案1】:

如果我手动执行此操作,我会使用 Unicode 编码而不是默认的 ANSI 保存 .txt 文件

Windows 在这里为您提供了误导性的术语。没有像“Unicode”这样的编码; Unicode 是以不同方式编码成字节的字符集。 Windows 称为“Unicode”的编码实际上是 UTF-16LE。这是一个每个代码单元两个字节的编码,不兼容 ASCII,通常不方便;网页往往不能很好地使用它。

(因为“ANSI”代码页的价值也与 ANSI 没有任何关系。另外还有变化......)

PrintWriter out = new PrintWriter(name + (fileNumber+i) + ".html");

这将使用 Java 默认编码创建一个文件,在您的情况下这可能是 ANSI 代码页。要指定不同的编码,请使用PrintWriter 的可选第二个参数:

PrintWriter out = new PrintWriter(name + (fileNumber+i) + ".html", "utf-8");

UTF-8 通常是一个不错的选择:作为 UTF,它可以存储所有 Unicode 字符,而且它也兼容 ASCII。

但是!您还使用默认编码读取字符串:

BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream()));

这可能不是页面的编码。同样,您可以使用可选参数指定编码:

BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream(), "utf-8"));

如果网页实际上以 UTF-8 格式提供,这将正常工作。

但如果不是呢?实际上有多种方法可以确定 HTML 页面的编码:

  1. 来自Content-Type: text/html;charset=... 标头参数(如果存在)。
  2. 来自&lt;?xml 声明,如果它被用作application/xhtml+xml
  3. 如果 (1) 和 (2) 不存在,则来自页面中的 &lt;meta&gt; 等效标记。
  4. 来自特定于浏览器的猜测启发式,这可能取决于用户设置。

你可以通过读取URL.getConnection().getContentType()并解析出参数得到(1)。要获得 (2) 或 (3),您必须实际解析文件,这是一个坏消息。 (4) 遥不可及。

您可以做的最一致的事情可能就是网络浏览器(IE 除外)在将独立网页保存到光盘时所做的事情:获取所提供的确切原始字节并将它们直接放入文件中,而无需任何尝试解码它们。然后您不必担心编码或行尾更改。这确实意味着 HTTP 标头中的任何字符集元数据都会丢失,但除了解析 HTML 并自己插入 &lt;meta&gt; 标记(可能太多了),您无能为力。

InputStream in = url.openStream();
OutputStream out = new FileOutputStream(name + (fileNumber+i) + ".html");

byte[] buffer = new byte[1024*1024];
int len;
while ((len = in.read(buffer)) != -1) {
    out.write(buffer, 0, len);
}

(来自this question 的nb 缓冲区复制循环,它提供了IOUtils 等替代方案。)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-06-04
    • 2018-11-18
    • 1970-01-01
    • 2013-06-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多