今天在做一个简单的Web爬虫,用.Net的HttpWebRequest获取页面信息,然后通过Regex获取页面上的连接,进行递归爬取,开始对http://blog.sunmast.com(Encoding为UTF-8)进行爬去的时候没有发现任何错误。爬取的东西显示正常,结果对其他一些中文网站(Encoding为GB2312)进行爬去的时候,获得的都为乱码,这也是必然,于是修改代码为:   HttpWebRequest req = (HttpWebRequest) WebRequest.Create("http://www.163.com");
   req.AllowAutoRedirect = true;
   req.MaximumAutomaticRedirections = 3;
   req.UserAgent = "Mozilla/6.0 (MSIE 6.0; Windows NT 5.1; Natas.Robot)";
   req.KeepAlive = true;
   req.Timeout = 4000;
    
   // Get the stream from the returned web response
   HttpWebResponse webresponse = null;
   try 
   {
        webresponse = (HttpWebResponse) req.GetResponse();
   } 
   catch(System.Net.WebException ex) 
   {
        string message = "error response exception:" + ex.Message;
        Console.WriteLine(message);
   }
   if (webresponse != null) 
   {
       StreamReader stream = new StreamReader
        (webresponse.GetResponseStream(), Encoding.GetEncoding("GB2312") );
        // TODO...
   }但是,用这样的程序来获取utf-8编码的中文网站,同时又会变成乱码。查看MSDN,看到HttpWebResponse有 ContentEncoding 和 CharacterSet,于是希望根据获得的网页的编码类型来进行StreamReader的编码。于是编码测试,可是却发现测试了很多网站(包括Microsoft,Sina)等,却都无法获取这两个参数,输出的结果均为string.Empty。在Google和Baidu上搜索不到此类问题的解决方案,在CodeProject找到两篇Article,却都是通过HttpWebResponse.ContentEncoding 属性获取页面的编码,可是我获取的为什么都是空字符串?

解决方案 »

  1.   

    不知道楼主有没有下载该网页.
    我自己写的是下载网页然后在从下载好的网页上面找连接.
    最初写的下载网页的也是用的streamreader,在dotnet下面需要用coding,但是无论任何coding好像都不太好用.我就用了另外一种方法,就不用去管coding是什么了.
    code如下:
    ----------------------------------
    string dir = "D:\\SelfPre\\Test\\Download"; //directory you wanna create the file
    String fileName = dir + "\\" + URLfileName + ".html";

    string URL = URLadd.Text.Trim();
    string URLfileName = "PreCode"; System.Net.HttpWebRequest URLReq;
    System.Net.HttpWebResponse URLRes;


    byte[] bBuffer = new byte[999];
    int iBytesRead  = 0;

    try 
    {
    FileStream FS = new FileStream(fileName,FileMode.Create);
    System.IO.Stream sChunks;
    URLReq = (HttpWebRequest)WebRequest.Create(URL);
    URLRes = (HttpWebResponse)URLReq.GetResponse(); sChunks = URLRes.GetResponseStream();
    do
    {
    iBytesRead = sChunks.Read(bBuffer,0,999);
    FS.Write(bBuffer,0,iBytesRead);
    }while(iBytesRead>0);
    sChunks.Close();
    FS.Close();
    }
    catch(Exception err)
    {
    MessageBox.Show(err.Message);
    }
      

  2.   

    发出帖子的时候好像弄错顺序了.
    //string URLfileName = "PreCode"; 这一行应该比String fileName = dir + "\\" + URLfileName + ".html";早. 
    不过该下载程序可以用于下载其他其他文件,测试过的有jpg为后缀的图片,或者swf为后缀的flash.
      

  3.   

    哈哈,谢谢夜雨了。这个方法果然不会出现了乱码的问题了 ̄
    streamreader这个是不好用,还是FileStream比较智能啊 ̄
      

  4.   

    能不能再问你个问题啊 ̄如何下面这种utf-8的编码在C#中转成中文呢
    "泡泡免费手机网" >>>泡泡免费手机网
      

  5.   

    Unicode编码去掉 &#x  ,(char)0x6CE1 就OK了。
      

  6.   

    目前我还没有发现系统有直接转换的,这样的功能自己写个函数代码也不是很长的。再说,什么都太现成了,不一定是好事。^^另问个问题
    http://community.csdn.net/Expert/topic/4530/4530153.xml?temp=.2030451
      

  7.   

    没错,我是想写个函数,查是不好写啊,我是本为是想把要换的字符串根据里面的分号分隔成一个数组,然再对数组中的每个元素进行(char),可是老提示不能从string 转为char ,有什么办法吗,我C#也是个新手,对于类型转换的问题还不是很了解,能帮帮我吗
      

  8.   

    大概的就这样了
    private string AmpToUnicode(string expression, string delimiter)
    {
    string result="";
    if(null == expression)
    {
    return result;
    }
    foreach(string s in expression.Split(delimiter.ToCharArray()))
    {
    if(s != string.Empty)
    {
    string tem = "0x"+s.Replace(";","");
    result += (char)Convert.ToUInt32(tem,16);
    }
    }
    return result;
    }Example: 
    string str = AmpToUnicode("泡泡免费手机网","&#x");
      

  9.   

    可以了,谢谢Optione(藐视不揭帖的)了,
    不知(夜雨)在吗,你说用FileStream把抓到下为的文件保存下来是可以了,可是我怎么用FileStream方法把这个保存下来的文件读取 到一个string字符串中呢~
      

  10.   

    1.
    没有试过用filestream读到一个string里面,我以前写的那个就是读完,和你那个差不多吧.
    StreamReader readStream = new StreamReader(sChunks,Encoding.UTF8);
    String loadcontent = readStream.ReadToEnd();//完整string
    FileInfo htmlfile = new FileInfo(fileName);
    StreamWriter writeFile = htmlfile.CreateText();
    writeFile.WriteLine(loadcontent);
    sChunks.Close();2.utf-8的编码在C#中转成中文.
    成片的编码没有遇到过,只是有时候处理过一点点的中文换成编码,还有就是将encoding不同的文件换成另外的coding,比如中文网页是GB2312的,现在可以换成unicode了.
    我想可以先设置设置byte[],将所有的utf-8的编码安装顺序读出来,然后encode成string就可以了吧.
      

  11.   

    StreamReader可以读取已有文件,所以如果文件已经创建完成,可以用readtoend读完.
    我用filestream是读一点写一点,直到完全写完.
    觉得读到一整个string里面也是需要把文件全部下载下来,这个过程也可以由创建一个临时文件来解决.
      

  12.   


    没错啊,我就是用filestream把文件 下载下来了,所以这个文件 是你本地是已经存在了,我现在是如果用StreamReader来读的话,又要指明是用什么编码(utf-8或gb2312),这样又回到了下载时的问题了,读出来的文件又有乱码了(因为我们不知道该文件是什么编码,所以也不知道该用什么编码方式进行读取),因为我要以文件中的内容进行分析,取出符合条件的内容,有没有一个方法能读取文件到一个string字符串中,且不用考虑要用什么编码一的读的,就像下载的那个方式一样,读到缓冲区,再写到文件中,这各地可以应用到我们读文件中就好了,这样我好方便进行分析,
      

  13.   

    不太清楚你想找什么.如果是找中文字可能就需要encoding,不过你可以试试用gb2312咯.偶没试过读取里面的中文,有点麻烦,现在英文系统版本下的dotnet有时候用messagebox显示出来的中文是比乱码还不好认的东西.
    不知道这种方法可以不.
    Encoding EC = System.Text.Encoding.GetEncoding("gb2312");
    StreamReader readStream = new StreamReader(filePath,EC);
      

  14.   

    你这种方法读取出来,如果是gb2312的页面是没问题,可是如果是utf-8的话,就会乱码了。
    但如果用:
    Encoding EC = System.Text.Encoding.GetEncoding("utf8");
    StreamReader readStream = new StreamReader(filePath,EC);
    这样读取出来的数据,如果是utf8的页面就正常了,但是如果是gb2312的话就又是乱码了,就是说两咱编码要用两种方式读取,我现在就是找不到一个统一的方法可以去读不管是gb2312还是utf8的页面都不会乱码的方法~~
      

  15.   

    还有我在用httpWebReqeust并用多线程进行网面抓取的时候,在抓取某些网站的时候会出现超时的问题,(因为在调试器的输出窗口中有出现“下载页面超时”的错误信息),然后线程就S在那里了,系统也是非常缓慢,这是httpWebRequest的问题,还是多线程的问题啊,你有遇到过这种情况吗
      

  16.   

    下载超时肯定是有的啦,把catch exception里面的msg去掉就可以了.
    无论是gateway problem还是protocol problem等等造成exception的,文件创建出来的大小都是0kb,里面是空白的.这个读取文件的时候是没有问题的.
      

  17.   

    去去掉啊,还是一样 啊,现在为止就一个网站会这样,我真是晕啊, ̄ ̄其它都不会出现这种情况 ̄ ̄不过昨天又重新抓了一次,有过一次是不会停顿的 ̄但后面也就不行了..经过测试不行了的原因有可能是跟网速有关,但是其它网站都很好啊,所以就理加郁闷了 ̄我在catch exception是这样写的,
    catch(WebException e)
    {
    return null;

    因为这个程序是要返回一个值,这个值就是整个页面的内容 ̄因为我下一步还要去这个页面中的所有链接进行分析,然后再抓取 ̄ ̄