C#使用C#WebClient或HttpWebRequest将网站下载到字符串中

时间:2011-09-22 16:19:48

标签: c# httpwebrequest webclient

我正在尝试下载网站的内容。但是对于某个网页,返回的字符串包含混乱的数据,包含许多 字符。

这是我最初使用的代码。

HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create(url);
req.Method = "GET";
req.UserAgent = "Mozilla/5.0 (Windows; U; MSIE 9.0; WIndows NT 9.0; en-US))";
string source;
using (StreamReader reader = new StreamReader(req.GetResponse().GetResponseStream()))
{
    source = reader.ReadToEnd();
}
HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument();
doc.LoadHtml(source);

我也尝试过使用WebClient的替代实现,但结果仍然相同:

HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument();
using (WebClient client = new WebClient())
using (var read = client.OpenRead(url))
{
    doc.Load(read, true);
}

从搜索开始,我猜这可能是编码的一个问题,所以我尝试了下面发布的两个解决方案,但仍然无法使其工作。

我似乎无法下载的违规网站是WikiPedia英文版(en.wikipedia.org / wiki / United_States)上的United_States文章。 虽然我已经尝试了许多其他维基百科文章,但没有看到这个问题。

3 个答案:

答案 0 :(得分:3)

在HtmlAgilityPack中使用内置加载器为我工作:

HtmlWeb web = new HtmlWeb();
HtmlDocument doc = web.Load("http://en.wikipedia.org/wiki/United_States");
string html = doc.DocumentNode.OuterHtml; // I don't see no jumbled data here

修改

将标准WebClient与您的用户代理一起使用将导致HTTP 403被禁止 - 使用此代替我工作:

using (WebClient wc = new WebClient())
{
    wc.Headers.Add("user-agent", "Mozilla/5.0 (Windows; Windows NT 5.1; rv:1.9.2.4) Gecko/20100611 Firefox/3.6.4");
    string html = wc.DownloadString("http://en.wikipedia.org/wiki/United_States");
    HtmlDocument doc = new HtmlDocument();
    doc.LoadHtml(html);
}

另见SO线程:WebClient forbids opening wikipedia page?

答案 1 :(得分:2)

响应是gzip编码的。 请尝试以下方法解码流:

<强>更新

根据BrokenGlass的评论设置,以下属性应解决您的问题(对我有用):

req.Headers[HttpRequestHeader.AcceptEncoding] = "gzip, deflate";
req.AutomaticDecompression = DecompressionMethods.Deflate | DecompressionMethods.GZip;

旧/手动解决方案:

string source;
var response = req.GetResponse();

var stream = response.GetResponseStream();
try
{
    if (response.Headers.AllKeys.Contains("Content-Encoding")
        && response.Headers["Content-Encoding"].Contains("gzip"))
    {
        stream = new System.IO.Compression.GZipStream(stream, System.IO.Compression.CompressionMode.Decompress);
    }

    using (StreamReader reader = new StreamReader(stream))
    {
        source = reader.ReadToEnd();
    }
}
finally
{
    if (stream != null)
        stream.Dispose();
}

答案 2 :(得分:1)

这就是我通常将页面抓取到字符串中的方式(它的VB,但应该很容易翻译):

req = Net.WebRequest.Create("http://www.cnn.com")
Dim resp As Net.HttpWebResponse = req.GetResponse()
sr = New IO.StreamReader(resp.GetResponseStream())
lcResults = sr.ReadToEnd.ToString

并且没有遇到任何问题。