惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

酷 壳 – CoolShell
酷 壳 – CoolShell
H
Hacker News: Front Page
P
Palo Alto Networks Blog
T
ThreatConnect
Apple Machine Learning Research
Apple Machine Learning Research
博客园_首页
T
True Tiger Recordings
P
Privacy & Cybersecurity Law Blog
B
Blog
IT之家
IT之家
Last Week in AI
Last Week in AI
F
Full Disclosure
Hacker News: Ask HN
Hacker News: Ask HN
C
Comments on: Blog
Microsoft Azure Blog
Microsoft Azure Blog
C
Cybersecurity and Infrastructure Security Agency CISA
Microsoft Security Blog
Microsoft Security Blog
博客园 - 【当耐特】
N
News and Events Feed by Topic
NISL@THU
NISL@THU
腾讯CDC
雷峰网
雷峰网
Security Latest
Security Latest
李成银的技术随笔
M
Microsoft Research Blog - Microsoft Research
L
LangChain Blog
L
Lohrmann on Cybersecurity
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
C
Check Point Blog
Y
Y Combinator Blog
Recent Announcements
Recent Announcements
博客园 - Franky
N
News | PayPal Newsroom
V
V2EX
A
About on SuperTechFans
The Register - Security
The Register - Security
月光博客
月光博客
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Google Online Security Blog
Google Online Security Blog
MyScale Blog
MyScale Blog
Cisco Talos Blog
Cisco Talos Blog
Vercel News
Vercel News
WordPress大学
WordPress大学
C
Cyber Attacks, Cyber Crime and Cyber Security
The Hacker News
The Hacker News
IntelliJ IDEA : IntelliJ IDEA – the Leading IDE for Professional Development in Java and Kotlin | The JetBrains Blog
IntelliJ IDEA : IntelliJ IDEA – the Leading IDE for Professional Development in Java and Kotlin | The JetBrains Blog
爱范儿
爱范儿
A
Arctic Wolf
L
LINUX DO - 最新话题
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More

博客园 - kwklover

给同为.NET开发者普及一点Oracle数据库经验 使用mencoder转换flv为ipad/iphone下能播放的mp4格式 - kwklover Lucene.net常见功能实现知识汇总 Lucene 1.9 多目录搜索的的一个bug 众里寻他千百度,蓦然回首,那人却在灯火阑珊处 问题总结:判断MS SQLSERVER临时表是否存在 小技巧:处理ASP提交的参数是经过GB2312 URL编码的 Lucene.net实现自定义排序笔记 模版引擎AderTemplate源代码分析笔记 T-SQL复习总结--用T-SQL创建,修改,管理,删除数据库 面向搜索的中文分词设计 需要整理研究的搜索引擎技术点(目录,无实际价值) 试用了一下Sqlite,总结和整理一下参考资料 数据结构与算法学习记录:快速排序 小总结:DotLucene如何才能快速生成索引? 小总结:如何表达用户是否禁止的概念 ? Web Spider提取编码方法总结 VS2005 Winform程序不能启动调试,别忘了启动Terminal Services服务[记录] 系统问题解决记录:IIS 500内部错误之解决办法
WebSpider的编码问题(乱码)浅析
kwklover · 2007-01-22 · via 博客园 - kwklover

这两天看到几篇关于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


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