JAVA 在抓取网页 怎么自动识别它的网页编码

JAVA 在抓取网页 怎么自动识别它的网页编码,第1张

JAVA 在抓取网页 怎么自动识别它的网页编码

1 看>

Java编译器只支持ANSI编码的源文件,无论源文件有没有BOM,也无论源文件使用了什么编码,Java编译器都以ANSI编码的方式读取源文件(注意,含有BOM的源文件将出现编译错误,UTF-16编码的源文件也会出现编译错误)。这一点不同于C/C++编译器,VC和GCC编译器都支持含有BOM的UTF-8编码的源文件。(DOM?BOM!)

Java编译器以ANSI(Windows简体中文版 *** 作系统的ANSI编码为GBK)编码的方式读取Java源文件进行编译,将源代码中的字符串(String)和字符(char)以UTF-8的形式存储在生成的字节码class文件中。(注意:根据JDK API文档,Java语言以UTF-16的形式表示字符和字符串。然而事实上,Java字节码文件却以UTF-8的形式存储字符和字符串。)

源文件中使用UTF-8编码的字符串,调用println函数发往控制台的也是UTF-8编码的字符串;源文件中使用ANSI编码的字符串,调用println函数发往控制台的还是ANSI编码的字符串;

为什么会乱码?因为DOS控制台并不像记事本那样能够自动识别字符串的编码,DOS控制台以预设的编码对字符串进行解析并加以显示。DOS中用于解析字符串的编码我们是可以自主设置的,在DOS窗口的标题栏右击,选择”默认值“,在对话框中的”默认代码页“中可以设置”GBK“或者”OEM-美国“为DOS默认的编码。你说的不错,DOS控制台确实不支持UTF-8的编码格式。

为什么输出英文字符串就没问题?因为UTF-8字符集和ANSI字符集都是ASCII字符集的超集,使用无BOM的UTF-8保存Java源文件,非ASCII字符只可能出现在字符串或字符中,而不会出现在源文件的其他位置,所以编译器并不会报错。UTF-8编码一般使用三个字节表示中文字符,ANSI编码使用2个字节表示中文字符。你的推理能力很好很强大,UTF-8的英文编码与ANSI是完全一样的。

BOM,Byte Order Mark,字节顺序标记。BOM其实很简单,就是文本文件开头的几个具有特殊含义的字节,例如,UTF-8的BOM是EF BB BF。以前文本文件是没有BOM的,以什么编码解析文本文件只能由文本编辑器自动判断,可是文本编辑器有时候会判断失误,使文本文件不能被正确读取。为了解决此问题,人们就发明了BOM,用BOM来标记文本文件使用的字符编码,这样文本编辑器就可以以BOM所代表的字符编码正确读取文本文档了。

朋友,字符编码的知识一两句话是说不清楚的,需要自己努力的学习与体会。Java语言建立于虚拟机之上,即使从事Java开发多年的程序员,也未必精通字符编码的知识。

java初学者都会接触到一个概念,既java的默认编码是uincode,但书上也就出现这句话而已,究竟是什么意思就没再说。其实对于一个程序员来说,一个平台的编码方式是不用了解的,因为这是他内部处理字符的方式,和我们顶层设计程序是没有多大关系(如果真要说有关系的话,一个就是你对这个平台的熟悉程度,另一个就只能是你要处理的字符奇葩到要考虑编译器有没有包括这个字符)。但这并不是指我们在编程的时候完全不用考虑编码问题,恰恰相反,编码问题是跨系统交流的基本。

那java哪里会用到编码问题呢?最常见的是流,下面有两个例子。1在linux下用java创建了一个文件(这里默认代码里没有指定编码),里面包括英文和中文,然后在windows下同样用java读取这个文件,并输出,结果中文出现了乱码;2android手机和电脑的两个java程序进行类似qq的信息交流,中文都是乱码。疑惑来了,java不是跨平台吗,而且默认编码就是unicode,为什么会有编码? 正如上面所说,java的系统编码是管理内部变量等信息的,是统一不能变的,但上面两个例子出现乱码的原因在于这些字符信息是从外界读取的,编码方式直接影响到字符的显示,比如gbk一个字符是1或2个字节,中文是2个,而utf8是1到4个字节不定,中文是3个,utf16是2个字节固定不变,所以很明显了,同样字节数的源信息可以每2个或者每3个字节表达一个中文,不同编码当然不同了,而且即使gbk和utf16都是两个字节表示一个中文,同样的二进制也对应不同的字符。所以从外部读取到这些byte信息后,就要指定编码,比如new

String(byte[],charset),当然,也可以在构建流的时候就指定,像new

InputStreamReader(InputStream,charset)等,但像BufferedReader等没有相应的构造函数,就只能把上面的InputStreamReader作为参数了。

总结:

1String和流(包括控制台的输出输入)的默认编码是根据系统而定,即jvm假设这些信息是当前系统创建的,windows默认中文是gbk,linux和mac是utf8(这里又来了,utf8和unicode是什么意思,简单地说,unicode是把每个字符和一个唯一的二进制码对应的标准,而utf是unicode

transformation

format,即如何表示每个唯一的二进制码,utf8,utf16和utf32是不同的编码方式);

2IDE设置的编码方式用于存取java源文件,对于在不同系统平台上共享代码很重要;

3java编译器采用utf8,即class文件的存储是用utf8,因为相对于utf16,utf8在处理英文占用内存小,而程序大部分都是英文;

4jvm运行时的编码方式是utf16,即jvm用utf8从class文件读取程序后再转化为utf16编码的字符串,因为utf16是2个字节,统一的长度更方便jvm申请数组等 *** 作;

5网页大部分是用utf8编码的,在html头几行有charset的信息,在对下载下来的网页进行解析时,要注意编码,谷歌百度在对搜索结果的解析时也是用utf8的,所以在涉及到网络时编码问题非常重要,本人曾经栽得很惨,当然了,谁叫windows的编码不是utf8;

6不知大家有没有经历过,如果编码弄错了,一般只有中文会出现乱码,而中文后面的英文是正确的,不合理啊,这不是类似多骨诺米牌吗,一个错了,后面不是全倒吗。所以别小看那些制定编码的专家,像utf8每个字节的前几位都用来表示一些信息,不同字节还不一样,而utf16也有,所以弄出了utf16le和utf16be

new String(agetBytes("ISO-8859-1"),"GB2312")

以单字节编码方式获取字符串流, 然后转中文格式,或者

new String(agetBytes("ISO-8859-1"),"UTF-8")

GBK是中国的解析字符标准,UTF-8是世界标准

java中编码:URLEncoderencode(strUri,"utf-8");

java中解码码:URLDecoderdecode(strUri,"utf-8");

java编码和解码        

流读取文件,具有转换编码功能的有:OutputStreamWriter和InputStreamReader,

构造器有如:

InputStreamReader(InputStream in, String charsetName)

创建使用指定字符集的 InputStreamReader。

OutputStreamWriter(OutputStream out, String charsetName)

创建使用指定字符集的 OutputStreamWriter。

处理字符串编码问题:

重新对获取的字符串进行编码:Byte[] bytes = strgetBytes(String encodeCharsetNam);

重新对bytes进行解码,创建新的字符串对象:str = new String(Byte[] bytes,String decodeCharsetName);

一般结合使用:str = new String(strgetBytes(String encodeCharsetName),String decodeCharsetName);

例如:resultName=new String(usernamegetBytes("ISO-8859-1"),"UTF-8");

还可以加入判断:

if(!CharsetforName("gbk")newEncoder()canEncode(str)){str = new Strin(strgetBytes("ISO-8859-1"),"UTF-8");}else{str = new String(strgetBytes("ISO-8859-1"),"gbk");}

处理请求参数传递编码问题:

java中编码:URLEncoderencode(strUri,"utf-8");

java中解码码:URLDecoderdecode(strUri,"utf-8");

js中编码:encodeURIComponent(strUri);encodeURI(strUri);escape(str);

js中解码:decodeURIComponent(strUri);decodeURI(strUri);unescape(str);

补充概念

URI组件:主机、端口、路径、查询参数、片段等。

URI组件分隔符::/#&[]@,冒号用于分隔协议和主机,/用于分隔主机和 路径,用于分隔路径和查询参数,&用于分隔多个查询参数等。

URI中的不安全字符或保留字符: ! ‘ ( ) ; : @ & = + $ , / # [ ] 他们具有特殊作用,例如上面的分隔作用。

URI允许出现的字符:只允许包含英文字母(a-zA-Z)、数字(0-9)、-_~4个特殊字符以及所有保留字符,其他字符均需要经过编码之后才能出现在Url中,比如使用保留字符的原意,而不是特殊作用。

js向java/jsp的编码与解码:

js中编码:encodeURI(encodeURI(strUri));decodeURIComponent(decodeURIComponent(strUri));

java/jsp中解码: javanetURLDecoderdecode(strUri,"UTF-8");

js中编码两次的问题:如果使用一次编码,在浏览器地址栏里,浏览器认为%是个转义字符,浏览器会把%与%之间的编码值,两位两位取出后进行解码。

然后再传递给处理页面,然后由处理页面进行再次解码,这样前面就缺少了一次编码过程,所以前面需要连续两次编码。

java中可以使用char类提供的charAt()方法来获得字符的unicode的编码值,示例如下:

public static String getUnicode(String source){ String returnUniCode=null; String uniCodeTemp=null; for(int i=0;i<sourcelength();i++){ uniCodeTemp = "\\u"+IntegertoHexString((int)sourcecharAt(i));//使用char类的charAt()的方法 returnUniCode=returnUniCode==nulluniCodeTemp:returnUniCode+uniCodeTemp; } Systemoutprint(source +" 's unicode = "+returnUniCode); return returnUniCode;//返回一个字符的unicode的编码值}

以上就是关于JAVA 在抓取网页 怎么自动识别它的网页编码全部的内容,包括:JAVA 在抓取网页 怎么自动识别它的网页编码、java初学者关于DOS控制台输出中文时乱码的问题、java使用unicode为默认编码是什么意思等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: https://www.outofmemory.cn/web/9536648.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-29
下一篇 2023-04-29

发表评论

登录后才能评论

评论列表(0条)

保存