整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

html乱码-解决gb2312编码导致乱码问题

html乱码-解决gb2312编码导致乱码问题

几天保存了网络上的一个页面,浏览器打开后,发现是乱码。如下图:

乱码网页

出现这个问题怎么处理呢?下面帮你解决

页面html源码

查看html,看到这里用了国标标准,看源码截图

<meta http-equiv="Content-Type" content="text/html; charset=gb2312" />

解决方法:

把gb2312改成utf-8即可

修改为utf-8

修改后的结果,如图:

修改后的展示

知识分享:

utf-8 和gb3212 的区别

utf-8 这个是国际通用字库,支持各种不同的语言

gb3212这个是中国的字库,支持简体中文和少数外语+一些符号,文件资源少一点

区别:utf-8跨平台兼容性更好,由于它字库更全所以加载会慢好多

html的charset属性

charset属性是定义HTML文档的字符编码格式。

常见的字符编码有:Unicode、utf-8、gbk、gb2312

其中:

gbk是国家标准的扩展版(增加了繁体并包含所有亚洲字符集)

Unicode是国际组织制定的旨在容纳全球所有字符的编码方案,包括字符集、编码方案等。又称为万国码、统一码、单一码

HTML标签相关的字符串格式化

string nl2br ( string $string )

nl2br() 就是将\n 替换成 <br> //javascript对\n才能够执行换行,对</br>是不能执行换行

htmlspecialchars() 把一些预定义的字符转换为 HTML 实体。

string htmlspecialchars(string,quotestyle,[character-set])

转换以下字符及对应的实体

& (和号) 成为 &
" (双引号) 成为 "
' (单引号) 成为 '
< (小于) 成为 <
> (大于) 成为 >

第二个参数: ENT_COMPAT 只转换双引号, 保留单引号, 为默认值 compat: 兼容性

ENT_QUOTES 同时转换两种引号 quotes: 引号

ENT_NOQUOTES 不对引号进行转换

<html>
<body>
<?php
$str="John & \" 'Adams'";
echo htmlspecialchars($str, ENT_COMPAT);
echo "<br />";
echo htmlspecialchars($str, ENT_QUOTES);
echo "<br />";
echo htmlspecialchars($str, ENT_NOQUOTES);
?>
</body>
</html>

输出结果:John & " 'Adams'

John & " 'Adams'

John & " 'Adams'

htmlentities() 可以将所有的非ASCII码字符转换为对应的实体代码;除字母、数字、\外, 汉字和键盘上其他字符都转换

<?php
$str="A 'quote' \" is <b>bold</b>" ;
echo htmlentities ( $str ); // 输出后源代码: A 'quote' is <b>bold</b>
echo htmlentities ( $str , ENT_QUOTES ); // 输出后源代码: A 'quote' is <b>bold</b>
?>

返回的结果:A 'quote' "is <b>bold</b>

A 'quote' "is <b>bold</b>

注意: htmlspecialchars()和htmlentities作用直接输出HTML脚本

htmlspecialchars()和htmlentities()函数对于转义字符"\"处理,不会转义实体代码,要么当转义字符对待,要么原样输出;

PHP中htmlentities和htmlspecialchars的区别

这两个函数的功能都是转换字符为HTML字符编码, 特别是url和代码字符串。防止字符标记被浏览器执行。

使用中文时没什么区别, 但htmlentities会格式化中文字符使得中文输入是乱码。

htmlentities转换所有的html标记, htmlspecialchars只格式化& ' " < 和 > 这几个特殊符号

addslashes() 在指定的预定义字符前添加反斜杠。

这些预定义字符是:单引号 (') 双引号 (") 反斜杠 (\) NULL字符(\x00)

提示:该函数可用于为存储在数据库中的字符串以及数据库查询语句准备合适的字符串。

注释:默认情况下,PHP 指令 magic_quotes_gpc 为 on,对所有的 GET、POST 和 COOKIE数据自动运行 addslashes()。

不要对已经被magic_quotes_gpc转义过的字符串使用 addslashes(),因为这样会导致双层转义。

遇到这种情况时可以使用函数 get_magic_quotes_gpc() 进行检测。(如:$c=(!get_magic_quotes_gpc())?addslashes($c):$c;)

在本例中,我们要向字符串中的预定义字符添加反斜杠:

<?php
$str="Who's John Adams?";
echo $str . " This is not safe in a database query.<br />";
echo addslashes($str) . " This is safe in a database query.";
?>

输出:

Who's John Adams? This is not safe in a database query.

Who\'s John Adams? This is safe in a database query.

<?php
header("Content-type:text/html; charset=utf-8");
$str="wo are \x0a studying \x00 php";
echo $str;
echo "<br>";
echo addslashes($str);
?>

输出:

wo are studying php

wo are studying >wo are studying \0 php< php



stripslashes() 删除反斜线("\")

在提交的表单数据中 ' " \ 等字符前被自动加上一个\ ,这是配置文件php.ini中选项magic_quotes_gpc在起作用,

默认是打开的,如果不处理则将数据保存到数据库时,有可能会被数据库误当成控制符号而引起错误。

通常htmlspecialchars()和stripslashes()函数复合的方式,联合处理表单中的提交的数据htmlspecialchars(stripslashes())

strip_tags()

string strip_tags ( string $str [, string $allowable_tags ] )

剥去 HTML、XML 以及 PHP 的标签。

<?php
echo strip_tags("Hello <b><i>world!</i></b>","<b>");
?>

输出结果:Hello world!

实例:

<?php
$str="<b>webserver;</b> & \ 'Linux' & Apache";
echo "$str"; //直接输出
echo "<br/>";
echo htmlspecialchars($str,ENT_COMPAT); //只转换双引号,为默认参数
echo "<br />";
echo htmlspecialchars($str,ENT_NOQUOTES); //不对引号进行转换
echo "<br />";
echo htmlspecialchars($str,ENT_QUOTES); //同时转换单引号和双引号
echo "<br />";
echo htmlentities($str); //将所有的非ASCII码字符转换为对应的实体代码
echo "<br />";
echo addslashes($str); //将" ' \ 字符前添加反斜线
echo "<br />";
echo stripslashes($str); //删除反斜线
echo "<br />";
echo strip_tags($str); //删除<html>标记
?>

输出结果:

webserver; & \ 'Linux' & Apache

者 | 丁彦军

责编 | 仲培艺

近日,有位粉丝向我请教,在爬取某网站时,网页的源代码出现了中文乱码问题,本文就将与大家一起总结下关于网络爬虫的乱码处理。注意,这里不仅是中文乱码,还包括一些如日文、韩文 、俄文、藏文之类的乱码处理,因为他们的解决方式是一致的,故在此统一说明。

乱码问题的出现

就以爬取 51job 网站举例,讲讲为何会出现“乱码”问题,如何解决它以及其背后的机制。

代码示例:

import requests
url="http://search.51job.com"
res=requests.get(url)
print(res.text)

显示结果:

打印 res.text 时,发现了什么?中文乱码!!!不过发现,网页的字符集类型采用的是 GBK 编码格式。

我们知道 Requests 会基于 HTTP 头部对响应的编码作出有根据的推测。当你访问 r.text 之时,Requests 会使用其推测的文本编码。你可以找出 Requests 使用了什么编码,并且能够使用 r.encoding 属性来改变它。

接下来,我们一起通过 Resquests 的一些用法,来看看 Requests 会基于 HTTP 头部对响应的编码方式。

print(res.encoding) #查看网页返回的字符集类型
print(res.apparent_encoding) #自动判断字符集类型

输出结果为:

可以发现 Requests 推测的文本编码(也就是网页返回即爬取下来后的编码转换)与源网页编码不一致,由此可知其正是导致乱码原因。

乱码背后的奥秘

当源网页编码和爬取下来后的编码转换不一致时,如源网页为 GBK 编码的字节流,而我们抓取下后程序直接使用 UTF-8 进行编码并输出到存储文件中,这必然会引起乱码,即当源网页编码和抓取下来后程序直接使用处理编码一致时,则不会出现乱码,此时再进行统一的字符编码也就不会出现乱码了。最终爬取的所有网页无论何种编码格式,都转化为 UTF-8 格式进行存储。

注意:区分源网编码 A-GBK、程序直接使用的编码 B-ISO-8859-1、统一转换字符的编码 C-UTF-8。

在此,我们拓展讲讲 Unicode、ISO-8859-1、GBK2312、GBK、UTF-8 等之间的区别联系,大概如下:

最早的编码是 ISO8859-1,和 ASCII 编码相似。但为了方便表示各种各样的语言,逐渐出现了很多标准编码。ISO8859-1 属于单字节编码,最多能表示的字符范围是 0-255,应用于英文系列。很明显,ISO8859-1 编码表示的字符范围很窄,无法表示中文字符。

1981 年中国人民通过对 ASCII 编码的中文扩充改造,产生了 GB2312 编码,可以表示 6000 多个常用汉字。但汉字实在是太多了,包括繁体和各种字符,于是产生了 GBK 编码,它包括了 GB2312 中的编码,同时扩充了很多。中国又是个多民族国家,各个民族几乎都有自己独立的语言系统,为了表示那些字符,继续把 GBK 编码扩充为 GB18030 编码。每个国家都像中国一样,把自己的语言编码,于是出现了各种各样的编码,如果你不安装相应的编码,就无法解释相应编码想表达的内容。终于,有个叫 ISO 的组织看不下去了。他们一起创造了一种编码 Unicode,这种编码非常大,大到可以容纳世界上任何一个文字和标志。所以只要电脑上有 Unicode 这种编码系统,无论是全球哪种文字,只需要保存文件的时候,保存成 Unicode 编码就可以被其他电脑正常解释。Unicode 在网络传输中,出现了两个标准 UTF-8 和 UTF-16,分别每次传输 8 个位和 16 个位。于是就会有人产生疑问,UTF-8 既然能保存那么多文字、符号,为什么国内还有这么多使用 GBK 等编码的人?因为 UTF-8 等编码体积比较大,占电脑空间比较多,如果面向的使用人群绝大部分都是中国人,用 GBK 等编码也可以。

也可以这样来理解:字符串是由字符构成,字符在计算机硬件中通过二进制形式存储,这种二进制形式就是编码。如果直接使用 “字符串??字符??二进制表示(编码)” ,会增加不同类型编码之间转换的复杂性。所以引入了一个抽象层,“字符串??字符??与存储无关的表示??二进制表示(编码)” ,这样,可以用一种与存储无关的形式表示字符,不同的编码之间转换时可以先转换到这个抽象层,然后再转换为其他编码形式。在这里,Unicode 就是 “与存储无关的表示”,UTF-8 就是 “二进制表示”。

乱码的解决方法

根据原因来找解决方法,就非常简单了。

方法一:直接指定 res.encoding

import requests
url="http://search.51job.com"
res=requests.get(url)
res.encoding="gbk"
html=res.text
print(html)

方法二:通过 res.apparent_encoding 属性指定

import requests
url="http://search.51job.com"
res=requests.get(url)
res.encoding=res.apparent_encoding
html=res.text
print(html)

方法三:通过编码、解码的方式

import requests
url="http://search.51job.com"
res=requests.get(url)
html=res.text.encode('iso-8859-1').decode('gbk')
print(html)

输出结果:

基本思路三步走:确定源网页的编码 A---GBK、程序通过编码 B---ISO-8859-1 对源网页数据还原、统一转换字符的编码 C-UTF-8。至于为啥出现统一转码这一步呢? 网络爬虫系统数据来源很多,不可能使用数据时,再转化为其原始的数据,这样做是很废事的。所以一般的爬虫系统都要对抓取下来的结果进行统一编码,从而在使用时做到一致对外,方便使用。

比如如果我们想讲网页数据保存下来,则会将起转为 UTF-8,代码如下:

with open("a.txt",'w',encoding='utf-8') as f:
 f.write(html)

总结

关于网络爬虫乱码问题,这里不仅给出了一个解决方案,还深入到其中的原理,由此问题引申出很多有意思的问题,如 UTF-8、GBK、GB2312 的编码方式怎样的?为什么这样转化就可以解决问题?

最后,多动脑,多思考,多总结,致每一位码农!

本文为作者投稿,版权归其所有。