C# WebClient 在从站点获取 html 时收到 403

C# WebClient receives 403 when getting html from a site

我正在尝试从站点下载 HTML 并解析它。我实际上只对头部的 OpenGraph 数据感兴趣。对于大多数使用 WebClient、HttpClient 或 HtmlAgilityPack 的网站,我会得到 403,例如:westelm.com

我已经尝试将 Headers 设置为与我使用浏览器时完全相同,但我仍然得到 403。这是一些代码:

string url = "https://www.westelm.com/m/products/brushed-herringbone-throw-t5792/?";

var doc = new HtmlDocument();

using(WebClient client = new WebClient()) {
  client.Headers["User-Agent"] = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.102 Safari/537.36";
  client.Headers["Accept"] = "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9";
  client.Headers["Accept-Encoding"] = "gzip, deflate, br";
  client.Headers["Accept-Language"] = "en-US,en;q=0.9";
  doc.Load(client.OpenRead(url));
}

此时,我收到 403。

我是不是遗漏了什么,或者站点管理员正在保护站点免受 API 请求?

我怎样才能完成这项工作?有没有更好的方法从站点获取 OpenGraph 数据?

谢谢。

我用你的问题解决了同样的问题。 IDK,如果你已经解决了这个问题,但我会告诉你它是如何为我工作的

出于同样的原因,一个页面给了我 403。问题是:您需要从代码中模拟“网络浏览器”,发送大量 headers.

我用过你的一个headers我没用过(比如Accept-Language)

虽然我没有使用 WebClient,但我使用 HttpClient 来解析网页

private static async Task<string> GetHtmlResponseAsync(HttpClient httpClient, string url)
    {
        using var request = new HttpRequestMessage(HttpMethod.Get, new Uri(url));
        request.Headers.TryAddWithoutValidation("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9");
        request.Headers.TryAddWithoutValidation("Accept-Encoding", "gzip, deflate, br");
        request.Headers.TryAddWithoutValidation("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.102 Safari/537.36");
        request.Headers.TryAddWithoutValidation("Accept-Charset", "UTF-8");
        request.Headers.TryAddWithoutValidation("Accept-Language", "en-US,en;q=0.9");

        using var response = await httpClient.SendAsync(request).ConfigureAwait(false);

        if (response == null)
            return string.Empty;

        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);
    }

如果对你有帮助,我很高兴。如果没有,我会在这里留下这个答案以帮助以后的其他人!