java 网页编码_JAVA如何判断网页编码

前言

最近做一个搜索项目,需要爬取很多网站获取需要的信息。在爬取网页的时候,需要获得该网页的编码,不然的话会发现爬取下来的网页有很多都是乱码。

分析

一般情况下,网页头信息会指定编码,可以解析header或者meta获得charset。但有时网页并没没有指定编码,这时就需要通过网页内容检测编码格式,通过调研,最好用的还是cpdetector。

1、首先,可从header中解析charset

网页头信息中的Content-Type会指定编码,如图:

0818b9ca8b590ca3270a3433284dd417.png

可以通过分析header,查找字符编码,代码如下:

private static String getEncodingByHeader(URL url) {

String strencoding = null;

HttpURLConnection httpConn = null;

try {

httpConn = (HttpURLConnection) url.openConnection();

httpConn.setRequestProperty("User-agent", "Mozilla/4.0");

Map> map = httpConn.getHeaderFields();

Set keys = map.keySet();

Iterator iterator = keys.iterator();

// 遍历,查找字符编码

String key = null;

String tmp = null;

while (iterator.hasNext()) {

key = iterator.next();

tmp = map.get(key).toString().toLowerCase();

// 获取content-type charset

if (key != null && key.equals("Content-Type")) {

int m = tmp.indexOf("charset=");

if (m != -1) {

strencoding = tmp.substring(m + 8).replace("]", "");

return strencoding;

}

}

}

} catch (IOException e) {

strencoding = null;

} finally {

try {

if (httpConn != null)

httpConn.disconnect();

} catch (Exception ex) {

log.error(ex);

}

}

return strencoding;

}

2、其次,可从网页meta中解析出charset

正常情况下,在写网页时,会指定网页编码,可在meta中读出来。如图:

0818b9ca8b590ca3270a3433284dd417.png

首先获取网页流,因为英文和数字不会乱码,可以解析meta,获得charset。

/**

* 从网页meta中解析出charset

*

* @param in2

* @return

*/

private static String getEncodingByMeta(InputStream inputs) {

String strencoding = null;

// StringBuffer sb = new StringBuffer();

String line;

BufferedReader in = null;

try {

in = new BufferedReader(new InputStreamReader(inputs));

while ((line = in.readLine()) != null) {

// sb.append(line);

if (line.contains("

// 解析html源码,取出区域,并取出charset

line = line.toLowerCase();

String strbegin = "

String strend = ">";

String strtmp;

int begin = line.indexOf(strbegin);

int end = -1;

int inttmp;

while (begin > -1) {

end = line.substring(begin).indexOf(strend);

if (begin > -1 && end > -1) {

strtmp = line.substring(begin, begin + end)

.toLowerCase();

inttmp = strtmp.indexOf("charset");

if (inttmp > -1) {

strencoding = strtmp.substring(inttmp + 7, end)

.replace("=", "").replace("/", "")

.replace("\"", "").replace("\'", "");

//.replace(" ", "#");

if (strencoding.indexOf(" ") != -1) {

strencoding = strencoding.substring(0, strencoding.indexOf(" "));

}

return strencoding;

}

}

line = line.substring(begin);

begin = line.indexOf(strbegin);

}

}

}

} catch (Exception e) {

System.err.println(e);

} finally {

if (in != null)

try {

in.close();

} catch (IOException e) {

e.printStackTrace();

}

}

return null;

}

3、当使用1、2解析不出编码时,使用cpdetector根据网页内容探测出编码格式

可以添加多个编码探测实例:

public static String getFileCharacterEnding(URL url) {

String fileCharacterEnding = null;

CodepageDetectorProxy detector = CodepageDetectorProxy.getInstance();

detector.add(JChardetFacade.getInstance());// 需要第三方JAR包:antlr.jar、chardet.jar

detector.add(ASCIIDetector.getInstance());

detector.add(UnicodeDetector.getInstance());

detector.add(new ParsingDetector(false));

detector.add(new ByteOrderMarkDetector());

Charset charset = null;

try {

charset = detector.detectCodepage(url);

} catch (Exception e) {

e.printStackTrace();

}

if (charset != null) {

fileCharacterEnding = charset.name();

}

return fileCharacterEnding;

}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值