类似于浏览器的 HttpClient 请求

37
当我使用HttpClient类调用www.livescore.com网站时,总是出现“500”错误。可能是服务器阻止了HttpClients的请求。
1)还有其他方法可以从网页获取HTML吗?
2)我如何设置标头以获取HTML内容?
当我像在浏览器中一样设置标头时,我总是得到奇怪的编码内容。
    http_client.DefaultRequestHeaders.TryAddWithoutValidation("Accept", "text/html,application/xhtml+xml,application/xml");
    http_client.DefaultRequestHeaders.TryAddWithoutValidation("Accept-Encoding", "gzip, deflate");
    http_client.DefaultRequestHeaders.TryAddWithoutValidation("User-Agent", "Mozilla/5.0 (Windows NT 6.2; WOW64; rv:19.0) Gecko/20100101 Firefox/19.0");
    http_client.DefaultRequestHeaders.TryAddWithoutValidation("Accept-Charset", "ISO-8859-1");

3)我该如何解决这个问题?有什么建议吗?

我在使用C#和HttpClientClass编写Windows 8 Metro风格的应用程序。


1
当您使用浏览器获取此URL时会发生什么? - Benny
在浏览器页面上显示正确。请查看http://www.livescore.com/。 - Norbert Pisz
你能发布整个函数吗? - tttony
4个回答

69

这里是你需要的内容 - 注意,你需要解压缩gzip编码的结果,按照 mleroy的方法:

private static readonly HttpClient _HttpClient = new HttpClient();

private static async Task<string> GetResponse(string url)
{
    using (var request = new HttpRequestMessage(HttpMethod.Get, new Uri(url)))
    {
        request.Headers.TryAddWithoutValidation("Accept", "text/html,application/xhtml+xml,application/xml");
        request.Headers.TryAddWithoutValidation("Accept-Encoding", "gzip, deflate");
        request.Headers.TryAddWithoutValidation("User-Agent", "Mozilla/5.0 (Windows NT 6.2; WOW64; rv:19.0) Gecko/20100101 Firefox/19.0");
        request.Headers.TryAddWithoutValidation("Accept-Charset", "ISO-8859-1");

        using (var response = await _HttpClient.SendAsync(request).ConfigureAwait(false))
        {
            response.EnsureSuccessStatusCode();
            using (var responseStream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false))
            using (var decompressedStream = new GZipStream(responseStream, CompressionMode.Decompress))
            using (var streamReader = new StreamReader(decompressedStream))
            {
                return await streamReader.ReadToEndAsync().ConfigureAwait(false);
            }
        }
    }
}

调用类似于:

var response = await GetResponse("http://www.livescore.com/").ConfigureAwait(false); // or var response = GetResponse("http://www.livescore.com/").Result;

不使用“Accept-Encoding”头信息,是否仍然可以实现相同的效果? - pim

26

5

需要注意以下几点。

  1. 该网站要求您提供用户代理,否则它将返回500 HTTP错误。

  2. 对livescore.com的GET请求会响应302到livescore.us。您需要处理重定向或直接请求livescore.us。

  3. 您需要解压gzip压缩的响应。

此代码适用于.NET 4客户端配置文件,您需要自己判断是否适用于Windows Store应用程序。

var request = (HttpWebRequest)HttpWebRequest.Create("http://www.livescore.com");
request.AllowAutoRedirect = true;
request.UserAgent = "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.17 (KHTML, like Gecko) Chrome/24.0.1312.57 Safari/537.17";

string content;

using (var response = (HttpWebResponse)request.GetResponse())
using (var decompressedStream = new GZipStream(response.GetResponseStream(), CompressionMode.Decompress))
using (var streamReader = new StreamReader(decompressedStream))
{
    content = streamReader.ReadToEnd();
}

OP没有使用HttpWebRequest,而是使用了HttpClient。但你对第1点和第3点的看法是正确的。 - Jesse C. Slicer
1
你说得对;好吧,原帖的作者似乎并没有决定使用HttpClient(可以看到他的第一个问题),所以希望这个回答仍然有用 :) - siger
谢谢!这是个好答案,但是在Windows 8中仅支持HttpClient。 - Norbert Pisz

1

我认为你可以非常确定他们已经尽一切努力阻止开发者进行屏幕抓取。

如果我使用以下代码从标准的C#项目尝试:

  var request = WebRequest.Create("http://www.livescore.com ");
  var response = request.GetResponse();

我收到了这个响应:
The remote server returned an error: (403) Forbidden.

2
是的,我知道 :) 但我们是开发人员,需要解决这样的问题 :) - Norbert Pisz
有付费的服务可用。 这是非法的黑客行为。也许你应该找另一个网站。 - markoo
4
非法?为什么?当你通过浏览器访问这个网站也是非法的吗? - Norbert Pisz
实时比分是一项大生意,大多数网站都有合作协议或可付费获取的XML源。 - markoo
未经他人许可复制其数据通常被视为非法行为,虽然大多数网站也在其服务条款或使用政策中涵盖了此事项。但我在livescore.com上没有找到相关条款。我仍建议您联系该网站,请求项目的授权,并询问他们是否有任何自己可供使用的API/Feed。 - Karl-Johan Sjögren

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接