[转4]关于HTML网页源码的字符编码(charset)格式(GB2312,GBK,UTF-8,ISO8859-1等)的解释
转自:http://www.crifan.com/summary_explain_what_is_html_charset_and_common_value_of_gb2312_gbk_utf_8_iso8859_1/
当你通过浏览器,打开某个网站,即某个url地址的时候,你所能正常看到网页的内容,各种文字,都可以正常显示,且没有显示乱码。
此过程,涉及到,浏览器帮你正确解析HTML源码,其中涉及到HTML网页源码的字符编码处理方面的问题。
和html字符编码有关的流程
和字符编码处理相关的大概逻辑是:
1.浏览器访问对应的url地址,并获取对应的html(或者,以及,其他的css,javascript等)网页源码
2.浏览器识别解析HTML源码内容
其中包含了,解析html的头部(header),找到对应的charset=xxx这部分的内容,然后把根据xxx所指示的字符编码类型,去解码对应的html内容,显示对应的文字,以保证不是乱码,可以正确的显示文字信息;
举个例子:
当我们通过浏览器,比如IE9,去打开对应的url地址:
http://www.songtaste.com/user/351979/
时,IE9中是可以正常显示对应网页内容的:
而此时,内部发生的过程就是:
1.IE9去访问url地址:
http://www.songtaste.com/user/351979/
去获得对应的html源码。
2.然后解析html源码并显示
其中包括了,解析html的头部信息,找到charset=gb2312,然后用GB2312编码格式去解码,然后就可以正常显示html中的内容,确保不是乱码了。
如何知道HTML源码是什么编码格式的
其中,关于html中charset部分的内容,此处详细解释一下:
此处我们可以通过Notepad++去查看当前html页面的源码:
然后就可以看到源码了,然后设置语言为HTML后,就可以方便看到对应的语法高亮后的源码了,其中就可以看到对应的html的header中的
1
|
<meta http-equiv= "content-type" content= "text/html;charset=gb2312" > |
部分的内容:
注:关于Notepad++的使用,以及如何设置为默认的HTML编辑器,不熟悉的可参考:
此处的
charset=gb2312
就是我们所要找的,html的字符编码类型。
如果我们按照此编码格式去解析html内容,就可以正常解析,不会出现乱码了。
注意:
1.之前就看到某处说过,有个别的html网页本身做的不规范,导致本身自己声明的是某种编码类型,但是实际上,并不全是该类型的编码,导致你去按照其所声明的编码去解析,有时候仍会出现乱码。
比如,其html中明明写的是charset=gb2312,但是实际上,其部分字符是属于GBK的,导致你按照gb2312去解码,有些字符仍会是乱码,而安装gbk去解码,就全都正常显示了,没有乱码了。
即实际上应该是charset=gbk。
对此,需要稍微注意一下。
注:关于gb2312,和gbk的关系,不了解的去看:
常见的html的编码类型(即常见的html的charset的值有哪些)
国内的网站,尤其是以前建的,好像很多还是GB2312(charset=gb2312),或者是GBK(charset=gbk)
但是越来越多的,都是采用兼容性更好的,包含字符更多的UTF-8编码的了(charset=utf-8)
国外的完整,如果只是某种语言的,比如英文的,好像也有采用iso8859-1的(charset=iso8859-1),同样,更多的网站,还是采用的是utf-8的。
注:同理,关于这些字符编码类型,如果不了解,可以参考:
ISO 8859
总结:
- 国内外的多数网站,都是采用charset=utf-8
- 部分国外网站采用charset=gb2312或charset=gbk
- 部分国外网站采用某种自己所属语言的编码,比如charset=iso8859-1
采用程序模拟采集并处理html源码时的注意事项
上述过程,如之前:
【整理】关于抓取网页,分析网页内容,模拟登陆网站的逻辑/流程和注意事项
所介绍的,内部逻辑都是通用的,所以可以采用工具抓取分析出来具体流程:
【教程】手把手教你如何利用工具(IE9的F12)去分析模拟登陆网站(百度首页)的内部逻辑过程
此时,接下来就是用程序模拟出来对应的流程了。
其中,就会涉及到,html源码的解析工作,涉及到html的字符编码问题。
此处,也是同理,需要通过程序,去将所获得的html源码,类似于浏览器(如IE9)一样,去按照charset所指定的编码去解码,才可以获得正常的,非乱码的内容。
Python语言
如我的教程:
或
【教程】模拟登陆网站 之 Python版(内含两种版本的完整的可运行的代码)
中所给出的代码所示,Python中处理html代码的话,根据后续处理流程不同,一般可分三种:
无需关心html的编码类型
有的时候,后续对于所获得html源码,即特定字符编码的字符串,是简单的应用,比如使用正则表达式re模块,去提取某些你所想要的内容,其中只涉及到英文类字符,
此时,即使不对html解码,也是可以直接从此特定编码的字符串,即html源码中,可以查找到你要的内容的。所以就无需额外操作了,直接提起即可。
比如,
中的:
1
2
3
4
5
6
|
#<h1 class="h1user">crifan</h1> foundH1user = re.search( \'<h1\s+?class="h1user">(?P<h1user>.+?)</h1>\' , respHtml); print "foundH1user=" ,foundH1user; if (foundH1user): h1user = foundH1user.group( "h1user" ); print "h1user=" ,h1user; |
直接从原始html中解码为对应的unicode字符串
如果是后续处理此html代码,是需要获得对应的unicode字符串,以便打印,和后续方面的提取出对应的中文等等应用,那么就需要将其解码为unicode字符串了。
类似的代码,就可以这么写了:
1
2
3
4
5
6
7
|
#假设当前respHtml是GBK编码类型的 htmlCharset = "GBK" ; decodedUnicodeStr = respHtml.decode(htmlCharset); #此时就已经获得了对应unicode字符串 decodedUnicodeStr 了,就可以做你要做的事情了 #比如打印出来看看 print "type(decodedUnicodeStr)=" , type (decodedUnicodeStr); print "decodedUnicodeStr=" ,decodedUnicodeStr; |
使用Python第三方库去解析html时的注意事项
此处目前只介绍关于BeautifulSoup的。
详细解释参见:
【总结】Python的第三方库BeautifulSoup的使用心得
中的"当解析非UTF-8或ASCII编码类型的HTML时,需要指定对应的字符编码"
C#语言
C#中,此处,和上述Python,基本类似。
即,取决于你后面的应用类型,也大概分为两类:
无需关心html的编码类型
如果后续的处理html,只是提前其中英文部分的字符串之类的,那么此处实际上,也是可以不关心html编码类型的。
(对应的,所说的html代码,实际上其中的中文字符,都是乱码,但是不影响后续的英文字符串的匹配的)
举例:
把
中的原先代码,稍作改动,就可以写出对应的完整的代码了:
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
|
//step1: get html from url string urlToCrawl = txbUrlToCrawl.Text; //generate http request HttpWebRequest req = (HttpWebRequest)WebRequest.Create(urlToCrawl); //use GET method to get url\'s html req.Method = "GET" ; //use request to get response HttpWebResponse resp = (HttpWebResponse)req.GetResponse(); //string htmlCharset = "GBK"; ////use songtaste\'s html\'s charset GB2312 to decode html ////otherwise will return messy code //Encoding htmlEncoding = Encoding.GetEncoding(htmlCharset); //StreamReader sr = new StreamReader(resp.GetResponseStream(), htmlEncoding); //here not designate html charset, so Chinese char in result is messy code StreamReader sr = new StreamReader(resp.GetResponseStream()); //read out the returned html string respHtml = sr.ReadToEnd(); //step2: extract expected info //<h1 class="h1user">crifan</h1> string h1userP = @"<h1\s+class=""h1user"">(?<h1user>.+?)</h1>" ; Match foundH1user = ( new Regex(h1userP)).Match(respHtml); //even though above respHtml contain messy Chinese chars, but not affect the english chars //so follow still can found the expected english string if (foundH1user.Success) { //extracted the expected h1user\'s value txbExtractedInfo.Text = foundH1user.Groups[ "h1user" ].Value; } else { txbExtractedInfo.Text = "Not found h1 user !" ; } |
从原始html中解码为对应的unicode字符串
当想要获得对应的,无乱码的,unicode类型的html的话,则需要用到将html解码为unicode。
C#中的做法是,在使用StreamReader时,指定对应的编码类型。
完整演示代码,之前在:
已经给出了,是如下的写法:
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
|
//step1: get html from url string urlToCrawl = txbUrlToCrawl.Text; //generate http request HttpWebRequest req = (HttpWebRequest)WebRequest.Create(urlToCrawl); //use GET method to get url\'s html req.Method = "GET" ; //use request to get response HttpWebResponse resp = (HttpWebResponse)req.GetResponse(); string htmlCharset = "GBK" ; //use songtaste\'s html\'s charset GB2312 to decode html //otherwise will return messy code Encoding htmlEncoding = Encoding.GetEncoding(htmlCharset); StreamReader sr = new StreamReader(resp.GetResponseStream(), htmlEncoding); //read out the returned html //here we got the, unicode (non-messy code) html string respHtml = sr.ReadToEnd(); //step2: extract expected info //<h1 class="h1user">crifan</h1> string h1userP = @"<h1\s+class=""h1user"">(?<h1user>.+?)</h1>" ; Match foundH1user = ( new Regex(h1userP)).Match(respHtml); if (foundH1user.Success) { //extracted the expected h1user\'s value txbExtractedInfo.Text = foundH1user.Groups[ "h1user" ].Value; } else { txbExtractedInfo.Text = "Not found h1 user !" ; } |
【总结】
关于html的编码,最简单解释就是:
找到html源码中的charset值,按照该编码类型去解码,即可获得正确的(Unicode,非乱码的)html字符串了。