spider JAVA如何判断网页编码 (转载)

原文链接 http://www.cnblogs.com/nanxin/archive/2013/03/27/2984320.html

前言

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

分析

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

  cpdetector自动检测文本编码格式,谁先返回非空,就以该结果为字符编码。内置了一些常用的探测实现类,这些探测实现类的实例可以通过add方法加进来,如等,detector按照“谁先返回非空的探测结果,就以谁的结果为准”的原则返回探测到的字符集编码。

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

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

  

  可以通过分析header,查找字符编码。

Map<String, List<String>> map = urlConnection.getHeaderFields();
Set<String> keys = map.keySet();
Iterator<String> 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;
        }
    }
}

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

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

  

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

StringBuffer sb = new StringBuffer();
String line;
try {
    BufferedReader in = new BufferedReader(new InputStreamReader(url
            .openStream()));
    while ((line = in.readLine()) != null) {
        sb.append(line);
    }
    in.close();
} catch (Exception e) { // Report any errors that arise
    System.err.println(e);
    System.err
            .println("Usage:   java   HttpClient   <URL>   [<filename>]");
}
String htmlcode = sb.toString();
// 解析html源码,取出<meta />区域,并取出charset
String strbegin = "<meta";
String strend = ">";
String strtmp;
int begin = htmlcode.indexOf(strbegin);
int end = -1;
int inttmp;
while (begin > -1) {
    end = htmlcode.substring(begin).indexOf(strend);
    if (begin > -1 && end > -1) {
        strtmp = htmlcode.substring(begin, begin + end).toLowerCase();
        inttmp = strtmp.indexOf("charset");
        if (inttmp > -1) {
            strencoding = strtmp.substring(inttmp + 7, end).replace(
                    "=", "").replace("/", "").replace("\"", "")
                    .replace("\‘", "").replace(" ", "");
            return strencoding;
        }
    }
    htmlcode = htmlcode.substring(begin);
    begin = htmlcode.indexOf(strbegin);
}

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

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

public static void getFileEncoding(URL url) throws MalformedURLException, IOException {
    CodepageDetectorProxy codepageDetectorProxy = CodepageDetectorProxy.getInstance();

    codepageDetectorProxy.add(JChardetFacade.getInstance());
    codepageDetectorProxy.add(ASCIIDetector.getInstance());
    codepageDetectorProxy.add(UnicodeDetector.getInstance());
    codepageDetectorProxy.add(new ParsingDetector(false));
    codepageDetectorProxy.add(new ByteOrderMarkDetector());

    Charset charset = codepageDetectorProxy.detectCodepage(url);
    System.out.println(charset.name());
    }
}
时间: 2024-10-19 02:56:44

spider JAVA如何判断网页编码 (转载)的相关文章

使用chardet模块判断网页编码

import chardet import urllib.request url='http://stock.sohu.com/news/' html = urllib.request.urlopen(url).read() chardit1 = chardet.detect(html) print(chardit1['encoding'])

【转载】java字符串的各种编码转换

java字符串的各种编码转换 来自:http://www.blogjava.net/rabbit/archive/2008/03/27/189009.html import java.io.UnsupportedEncodingException; /** * 转换字符串的编码 */public class ChangeCharset { /** 7位ASCII字符,也叫作ISO646-US.Unicode字符集的基本拉丁块 */ public static final String US_AS

【转载】python抓取网页时候,判断网页编码格式

在web开发的时候我们经常会遇到网页抓取和分析,各种语言都可以完成这个功能.我喜欢用python实现,因为python提供了很多成熟的模块,可以很方便的实现网页抓取.但是在抓取过程中会遇到编码的问题,那今天我们来看一下如何判断网页的编码:网上很多网页的编码格式都不一样,大体上是GBK,GB2312,UTF-8等.我们在获取网页的的数据后,先要对网页的编码进行判断,才能把抓取的内容的编码统一转换为我们能够处理的编码,避免乱码问题的出现. 使用chardet模块 1 #如果你的python没有安装c

java 抓取网页图片

? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86

Java Object 序列化与单例模式 [ 转载 ]

Java Object 序列化与单例模式 [ 转载 ] @author Hollis 本文将通过实例+阅读Java源码的方式介绍序列化是如何破坏单例模式的,以及如何避免序列化对单例的破坏. 单例模式,是设计模式中最简单的一种.通过单例模式可以保证系统中一个类只有一个实例而且该实例易于外界访问,从而方便对实例个数的控制并节约系统资源.如果希望在系统中某个类的对象只能存在一个,单例模式是最好的解决方案.关于单例模式的使用方式,可以阅读单例模式的七种写法 但是,单例模式真的能够实现实例的唯一性吗? 答

Java实现简单网页抓取

需求说明:使用Java抓取网页信息,并以字符串的形式返回. 使用Java代码实现: package net.ibuluo.spider.util; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.Reader; import java.net.MalformedURLException; import java.net.URL; /**

java兑现html网页的gzip解压

java实现html网页的gzip解压 在对网页抓包中发现,返回的很多网页是经过压缩的,比如访问谷歌首页,返回的头文件中包含Content-Encoding gzip 使用gzip可以省下很多网页流量,在网速一定的情况下,可以提高访问效率,我们用java访问时如何可以得到gzip的返回,并且我们如何解析返回的gzip呢? 我们以访问http://www.baidu.com/为例我们用URL的openStream方法直接访问时并不返回gzip压缩数据,这是因为时候返回gzip需要判断浏览器是否支持

Java类之间的关联关系(转载)

Java类之间的关联关系 UML类图中的关系分为四种:泛化.依赖.关联.实现:关联关系又可以细化为聚合和组合.一.泛化(Generalization)泛化是父类和子类之间的关系,子类继承父类的所有结构和行为.在子类中可以增加新的结构和行为,也可以覆写父类的行为. 一般用一个带空心箭头的实线表示泛化关系,UML图如下: 泛化对应Java中继承关系,即子类继承父类中出private修饰外的所有东西(变量.方法等).示例代码: public class Animal { } public class

Java输入输出流总结(转载)

Java输入输出流总结 一.介绍 流是数据源或数据目标的输入或输出设备的抽象表示.支持流输入和输出的主要包是java.io,但是也有其他的包,比如java.nio.file.java.io包支持两种类型的流--包含二进制数据的字节流和包含字符数据的字符流. 当写数据到字节流中时,数据会以字节序列的形式写到流中,与它们在内存中的形式完全一样,在这个过程中不会发生数据转换.即java.io包中的InputStream和OutputStream的派生类,通常用来读取二进制数据,如图像和声音. 将字符串