ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

Java-爬行非英语网站的编码问题

2019-12-07 23:03:13  阅读:279  来源: 互联网

标签:encoding utf-8 java internationalization web-crawler


我试图以字符串的形式获取网页的内容,但发现了一个问题how to write a basic web crawler,该问题声称(似乎)处理了编码问题,但是那里提供的代码适用于美国/英语网站,无法正确处理其他语言.

这是一个完整的Java类,演示了我所指的内容:

import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.regex.Matcher;
import java.util.regex.Pattern;


public class I18NScraper
{
    static
    {
        System.setProperty("http.agent", "");
    }

    public static final String IE8_USER_AGENT = "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0; WOW64; Trident/4.0; SLCC1; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; InfoPath.2)";

  //https://stackoverflow.com/questions/1381617/simplest-way-to-correctly-load-html-from-web-page-into-a-string-in-java
    private static final Pattern CHARSET_PATTERN = Pattern.compile("text/html;\\s+charset=([^\\s]+)\\s*");
    public static String getPageContentsFromURL(String page) throws UnsupportedEncodingException, MalformedURLException, IOException {
        Reader r = null;
        try {
            URL url = new URL(page);
            HttpURLConnection con = (HttpURLConnection)url.openConnection();
            con.setRequestProperty("User-Agent", IE8_USER_AGENT);

            Matcher m = CHARSET_PATTERN.matcher(con.getContentType());
            /* If Content-Type doesn't match this pre-conception, choose default and 
             * hope for the best. */
            String charset = m.matches() ? m.group(1) : "ISO-8859-1";
            r = new InputStreamReader(con.getInputStream(),charset);
            StringBuilder buf = new StringBuilder();
            while (true) {
              int ch = r.read();
              if (ch < 0)
                break;
              buf.append((char) ch);
            }
            return buf.toString();
        } finally {
            if(r != null){
                r.close();
            }
        }
    }

    private static final Pattern TITLE_PATTERN = Pattern.compile("<title>([^<]*)</title>");
    public static String getDesc(String page){
        Matcher m = TITLE_PATTERN.matcher(page);
        if(m.find())
            return m.group(1);
        return page.contains("<title>")+"";
    }

    public static void main(String[] args) throws UnsupportedEncodingException, MalformedURLException, IOException{
        System.out.println(getDesc(getPageContentsFromURL("http://yandex.ru/yandsearch?text=%D0%A0%D0%B5%D0%B7%D1%83%D0%BB%D1%8C%D1%82%D0%B0%D1%82%D0%BE%D0%B2&lr=223")));
    }
}

哪个输出:

???????????&nbsp;&mdash; ??????: ??????? 360&nbsp;???&nbsp;???????

虽然应该是:

Результатов&nbsp;&mdash; Яндекс: Нашлось 360&nbsp;млн&nbsp;ответов

您能帮我了解我在做什么错吗?尝试强制执行UTF-8之类的操作无济于事,尽管这是源和HTTP标头中列出的字符集.

解决方法:

您看到的问题是Mac上的编码不支持西里尔文字.我不确定在Oracle JVM上是否如此,但是当Apple生产自己的JVM时,是the default character encoding for Java was MacRoman.

启动程序时,请指定file.encoding系统属性以将字符编码设置为UTF-8(这是Mac OS X默认使用的字符).请注意,必须在启动时进行设置:java -Dfile.encoding = UTF-8 …;如果您以编程方式设置它(通过调用System.setProperty()),则为时已晚,该设置将被忽略.

每当Java需要将字符编码为字节时(例如,在将文本转换为字节以写入标准输出或错误流时),除非您明确指定其他字符,否则它将使用默认值.如果默认编码无法编码特定字符,则将替换一个合适的替换字符.

如果编码可以处理Unicode替换字符U FFFD,则使用(.)否则,问号(?)是常用的替换字符.

标签:encoding,utf-8,java,internationalization,web-crawler
来源: https://codeday.me/bug/20191207/2087163.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有