这两天看到几篇关于WebSpider的文章。其中关于抓取网页出现的编码格式问题大家都比较感兴趣,以前在参与帮看网的开发时也遇到过。不过那时候忙于ITDB的BBS开发,没有时间去研究。今天看到解决网爬工具爬取页面信息出现乱码的问题 ,刚好最近离职赋闲在家。所以又挑起了我研究学习的兴趣。现在把我的“研究成果”和大家探讨下:
  下面我按照我解决问题的思路来行文
   1,要根本解决编码问题,先要从编码的理论入手。
   2,计算机是一门实践的科学,多动手尝试吧。

一,和编码相关的理论知识:
  中文编码处理(1) -- 编码与字符集,我摘录几句:
  如果我们读不同编码的文件 到程序内部处理再保存程另一个文件 涉及到三次编码问题
  1 读入文件使用什么编码
  2 程序中使用什么编码
  3 写出文件使用什么编码
  看到这里。可以知道如果自以为先用某种格式把数据从流中读取出来,然后判断,再转换的方式处理编码问题,那么方法本身就错了。结果自然就是不可预期的。当然上面的话并不代表权威。仅仅做为一种分析的参考。

二,http协议和html的规范关于如何得到一个页面的字符编码三种方法:
1.An HTTP "charset" parameter in a "Content-Type" field.
example:
Content-Type: text/html; charset=EUC-JP

2.A META declaration with "http-equiv" set to "Content-Type" and a value set for "charset".
example:
<META http-equiv="Content-Type" content="text/html; charset=EUC-JP">

3.The charset attribute set on an element that designates an external resource.
example:
<A href="http://www.w3.org/" charset="ISO-8859-1">W3C Web site</A>

现在先贴一段常见的抓取网页的代码,方便后续的讨论:

WebRequest webRequest = WebRequest.Create(url);
WebResponse webResponse = webRequest.GetResponse();
 Stream stream = webResponse.GetResponseStream();

 StreamReader sr = new StreamReader(stream, Encoding.Default);
 string html = sr.ReadToEnd();
 return html;

常见的识别编码格式都是要么从HttpWebResponse的ContentEncoding和CharacterSet去分析,要么从提取的网页里的分析(二列出的三种方法),现在的问题就出在既然HttpWebResponse的ContentEncoding和CharacterSet并不可靠。而要从流读数据必须指定编码,但现在并不能可靠的确定数据源的正确编码,而尝试用一种编码格式读然后转又会遭遇上叙一所说的问题。这让我想起了我以前写过的“由一道面试题引起的疑问与思考”里关于XML编码格式问题,里面谈到BOM(字节顺序标记)的问题,转其中的几句话:
 W3C定义了三条XML解析器如何正确读取XML文件的编码的规则:
 1,如果文挡有BOM(字节顺序标记,一般来说,如果保存为unicode格式,则包含BOM,ANSI则无),就定义了文件编码
 2,如果没有BOM,就查看XML声明的编码属性
 3,如果上述两个都没有,就假定XML文挡采用UTF-8编码

其实网页也是一种文本格式的东西,其规则也应该类似,我搜索了下,找到更详细的资料:
 1,如果流中是以0xef, 0xbb, 0xbf开头的话,可以确定编码格式utf-8的
 2,如果流中是以0xff,0xfe开头的话,可以确定编码格式是utf-16的

如果仅仅按照上面所列两种情况去判断的,还显然不够严谨,但是到目前为止,我还没找到更详细的关于各种编码的BOM的更多资料。
写到这里,我不得不告诉你,上面的一切探索对于.net来说都是徒劳的,因为.net已经内置了这样的判断方法:
  StreamReader sr = new StreamReader(stream, Encoding.Default,true);
就多加一个true,ms帮你完成BOM的检测。具体的你可以看MSDN的帮助文挡。

我在开篇说到计算机是一门实践的科学,我测试了几个网页都没发现乱码问题。当然这并不表示就完全没有问题,只是一时没找到让它乱码的网页,如果你发现了,请你一定要告诉我。我们一起来研究下。

最后,我想推翻我刚才的结论:上面的一切探索对于.net来说都是徒劳的;因为我看到下面的代码的时候,我知道why,而不仅仅是how !
Reflector出来的StreamReader关于通过BOM检测编码格式的代码:

DetectEncoding
private void DetectEncoding()
        {
            if (this.byteLen >= 2)
            {
                this._detectEncoding = false;
                bool flag1 = false;
                if ((this.byteBuffer[0] == 0xfe) && (this.byteBuffer[1] == 0xff))
                {
                    this.encoding = new UnicodeEncoding(true, true);
                    this.CompressBuffer(2);
                    flag1 = true;
                }
                else if ((this.byteBuffer[0] == 0xff) && (this.byteBuffer[1] == 0xfe))
                {
                    if (((this.byteLen >= 4) && (this.byteBuffer[2] == 0)) && (this.byteBuffer[3] == 0))
                    {
                        this.encoding = new UTF32Encoding(false, true);
                        this.CompressBuffer(4);
                    }
                    else
                    {
                        this.encoding = new UnicodeEncoding(false, true);
                        this.CompressBuffer(2);
                    }
                    flag1 = true;
                }
                else if (((this.byteLen >= 3) && (this.byteBuffer[0] == 0xef)) && ((this.byteBuffer[1] == 0xbb) && (this.byteBuffer[2] == 0xbf)))
                {
                    this.encoding = Encoding.UTF8;
                    this.CompressBuffer(3);
                    flag1 = true;
                }
                else if ((((this.byteLen >= 4) && (this.byteBuffer[0] == 0)) && ((this.byteBuffer[1] == 0) && (this.byteBuffer[2] == 0xfe))) && (this.byteBuffer[3] == 0xff))
                {
                    this.encoding = new UTF32Encoding(true, true);
                    flag1 = true;
                }
                else if (this.byteLen == 2)
                {
                    this._detectEncoding = true;
                }
                if (flag1)
                {
                    this.decoder = this.encoding.GetDecoder();
                    this._maxCharsPerBuffer = this.encoding.GetMaxCharCount(this.byteBuffer.Length);
                    this.charBuffer = new char[this._maxCharsPerBuffer];
                }
            }
        }

水平有限,不妥之处,欢迎指正。

WebSpider的编码问题(乱码)浅析相关推荐

  1. java菱形乱码 编码_JAVA:编码与乱码问题

    一.为什么要编码? 由于人类的语言太多,因而表示这些语言的符号太多,无法用计算机的一个基本的存储单元----byte来表示,因而必须要经过拆分或一些翻译工作,才能让计算机能理解. byte一个字节即8 ...

  2. php 使用css乱码,分享CSS字符编码引起乱码快速解决的方法

    下面小编就为大家带来一篇分享CSS字符编码引起乱码快速解决的方法.小编觉得挺不错的,现在就分享给大家,也给大家做个参考.一起跟随小编过来看看吧 乱码引起的CSS失效原理: 由于一个中文是两个字符组成, ...

  3. 编码与乱码(05)---GBK与UTF-8之间的转换--转载

    原文地址:http://www.blogjava.net/pengpenglin/archive/2010/02/22/313669.html [GBK转UTF-8] 在很多论坛.网上经常有网友问&q ...

  4. 文章已转移到“字符集编码与乱码”分类下

    2019独角兽企业重金招聘Python工程师标准>>> 取消此"乱码探源"分类,之下的文章已经转移到"字符集编码与乱码(我的网站)"下. 也可 ...

  5. 汉字乱码_彻底搞懂这烦人的编码与乱码!

    ❝ 我们平时在处理文本文件或者网络请求时,时不时会遇到乱码的情况,这篇文章就带你彻底搞懂编码和乱码 ❞ 首先,我们要知道,在计算机中,一切都是用0和1来表示的.普通的txt文件.或者客户端发过来的数据 ...

  6. Java编码与乱码问题

    一.为什么要编码? 由于人类的语言太多,因而表示这些语言的符号太多,无法用计算机的一个基本的存储单元----byte来表示,因而必须要经过拆分或一些翻译工作,才能让计算机能理解. byte一个字节即8 ...

  7. python 乱码 无效_python学习第四天:python基础(字符编码和乱码到底咋回事儿)...

    字符编码 这得从字符编码开始说起: 字符串也是一种数据类型,但是,字符串比较特殊的是还有一个编码问题.因为计算机只能处理数字,如果要处理文本,就必须先把文本转换为数字才能处理. 最早的计算机在设计时采 ...

  8. Chrome网页编码显示乱码

    今天打开Chrome浏览器,网页编码显示乱码了,这还是第一次遇到这样的情况 解决办法: 第一步  在chrome网上应用店下载  Set Character Encoding 这是下载地址: http ...

  9. Java 字符的 编码 与 乱码 和恢复

    这里写目录标题 常见非Unicode编码 1.ASCII 2.ISO 8859-1 3.Windows-1252 4.GB2312 5.GBK 6.GB18030 7.Big5 8.编码汇总 2.3. ...

最新文章

  1. BGP协议路由聚合—AS-SET的使用
  2. 如何实现分享网站文章到微信朋友圈时显示指定缩略图或LOGO
  3. vuex保存用户信息_你想要的,vuex干货分享
  4. python 时间序列分析之ARIMA(不使用第三方库)
  5. Python_多元回归(一元回归)
  6. LINUX优化--打开文件数保存方法
  7. Tree Context Menu
  8. 中国智能语音行业发展趋势预测:市场规模将达159.7亿[图]
  9. 2016年 CSS 库、框架和工具新生榜 TOP 50
  10. tarjan 割点 割边
  11. 遥感基础编程语言IDL介绍
  12. 4)Thymeleaf th:each 循环迭代与 th:if、th:switch 条件判断
  13. 搭建vlmcsd KMS服务器
  14. 抖音SEO优化源码,抖音搜索排名系统,矩阵同步分发。
  15. 百度“哼唱”音乐搜索
  16. 教你制作第一个C++游戏!#1 引入
  17. Lifeline功能介绍01——日历及时间轴的查看
  18. 利用计算机网络实现OA的功能,oa系统是什么,oa系统功能介绍
  19. 倾斜摄影三维建模软件photoscan教程 [转]
  20. DS18B20测量温度

热门文章

  1. 登顶Nature | DeepMind用AI首次实现数学领域重大进展,助力科学家证实两大猜想
  2. 北大副校长詹启敏回应“25篇论文造假”,​PubPpeer到底靠不靠谱?
  3. 拿下赌场新客户,但马斯克“超级隧道”何时才能颠覆地面交通?
  4. 马斯克39也火星计划PPT
  5. 2019年中国科创板全面解读报告
  6. 图解|2018年度中国科学十大进展
  7. 【干货51页PPT】深度学习理论理解探索
  8. 路易斯·罗森伯格与「群体智能」
  9. 那么多GAN哪个好?谷歌大脑泼来冷水:都和原版差不多
  10. 腾讯员工人均年薪84.7万,马化腾:员工心理健康最重要