c# 后台传到前台乱码_c# 网络爬虫 乱码 问题解决方法

笔者最近的项目中用到了HtmlAgilityPack,让它担当网络爬虫的html dom parser解析模块。在使用中发现它对中文处理并不好,在下载gb2312编码的网页时多半会出现乱码,搜索网络上的解决方案大多不太成熟。本文中为各位介绍 .Net平台 下c# httpwebrequest httpwebresponse 应用中出现 中文 乱码的通用解决方法。

797cd42c9aaf1847996e1ba1b9d34859.png

乱码

中文 乱码 出现的原因

正常情况下,网络服务器会发出正确的Content-Encoding HTTP标头。似乎80%以上的网站都会这么做,浏览器或网络爬虫读取到HTTP 标头后,设置正确的中文 编码,然后显示给用户。但剩下的20%呢?如果你自己开发一个网络爬虫,中文 乱码 绝对会成为一个噩梦,解决的方式有很多种。

c# HttpWebResponse GetResponseStream() 处理

不管怎么说,处理网络流是第一步,如果确定了URI指向的MIME Type是html文本,有三种方式获取文本的编码格式。

HTTP Header Charset 或 Content-Encoding

在使用StreamReader读取流时,使用detectEncodingFromByteOrderMarks自动检测

读取

前两种方式有它的局限性,第一种方式的缺陷很明显,即很多网络服务器并不发出Content-Encoding或Charset HTTP标头,这也是大多数时候出现 中文 乱码 的重要因素。

第二种方式的局限性在于detectEncodingFromByteOrderMarks只能自动识别 UTF-8、Little-Endian Unicode 和 Big-Endian Unicode 文本,对GB2312编码的html文本则无能为力了。

针对上面两种方式的缺陷,最后只能检测 meta元素中的Content-Type了。下面是它C#实现方式:

///

/// Check Html Page Encoding

/// site: http://www.cnphp.info/howto-solve-encoding-problem-in-csharp.html

/// author: freemouse

///

/// NetWork Stream

/// Ecnoding in

/// return read content from stream s

private string CheckEncoding(Stream s,ref Encoding enc)

{

string pattern = "[-\\w]+)";

Regex charSetPattern = new Regex(pattern, RegexOptions.IgnoreCase);

StringBuilder strBuilder = new StringBuilder();

StringBuilder retBuilder = new StringBuilder();

string line = "";

while ( ReadLine(s,strBuilder) )

{

line = strBuilder.ToString();

if (line.Trim().StartsWith("

strBuilder.Remove(0, strBuilder.Length);

retBuilder.AppendLine(line);

Match m = charSetPattern.Match(line);

if (m.Success)

{

string strEnc = m.Groups["charset"].Value;

try

{

enc = Encoding.GetEncoding(strEnc);

break;

}

catch (Exception)

{

//throw new Exception(err.Message);

return retBuilder.ToString();

}

}

}

if (enc != null)

{

return enc.GetString(Encoding.GetEncoding("ISO-8859-1").GetBytes(retBuilder.ToString()));

}

return retBuilder.ToString();

}

///

/// Read a line from NetwrokStream

/// site: http://www.cnphp.info/howto-solve-encoding-problem-in-csharp.html

/// author: freemouse

///

/// Stream to Read

/// Line storage

/// if is end of Stream return false

private bool ReadLine(Stream s,StringBuilder strBuilder)

{

int iChar = -1;

do

{

if (iChar != -1)

{

if (iChar <= 65 && iChar >= 90) {

strBuilder.Append(iChar+32); }

else

strBuilder.Append((char)iChar);

}

} while ((iChar = s.ReadByte()) != (int)'\n' && iChar != -1);

if ( iChar != -1) return true;

return false;

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值