7

我最近发现以下内容不适用于某些网站,例如 IMDB.com。

class Program
    {
        static void Main(string[] args)
        {
            try
            {
                System.Net.WebRequest wc = System.Net.WebRequest.Create("http://www.imdb.com"); //args[0]);

                ((HttpWebRequest)wc).UserAgent = "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/525.19 (KHTML, like Gecko) Chrome/0.2.153.1 Safari/525.19";
                wc.Timeout = 1000;
                wc.Method = "HEAD";
                WebResponse res = wc.GetResponse();
                var streamReader = new System.IO.StreamReader(res.GetResponseStream());

                Console.WriteLine(streamReader.ReadToEnd());
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }
    }

它返回一个 HTTP 405(不允许的方法)。我的问题是,我使用与上面非常相似的代码来检查链接是否有效以及绝大多数情况下它是否正常工作。我可以将它切换到等于 GET 的方法并且它可以工作(随着超时的增加),但这会使事情减慢一个数量级。我假设 405 响应是 IMDB 服务器端的服务器配置。

有没有办法让我在.NET中以轻量级的方式做与上面相同的事情?或者,有没有办法修复上述代码,使其作为与 imdb 一起使用的 GET 请求工作?

4

3 回答 3

6

使用套接字(而不是HttpRequestWebClient)自己打开连接,并在阅读状态代码后立即关闭流。幸运的是,状态码靠近响应流的顶部 :)

于 2011-03-18T15:54:10.377 回答
4

您必须澄清“轻量级”的含义。你想达到什么目的?

您是否可以使用 GET/POST/HEAD/DELETE/etc 将取决于 URL 以及在该 URL 的服务器上运行的应用程序中配置的内容。

如果您要做的只是查看是否可以在不实际下载内容的情况下建立连接,您可以尝试使用套接字启动到端口 80 的连接,但仅通过更改并没有真正可靠或普遍支持的方式HTTP 方法。

于 2011-03-18T15:41:19.277 回答
4

如果 HEAD 返回 405,则意味着服务器不支持 HEAD(至少对于该 URL),您将转而使用 GET。大多数站点都应该支持 HEAD,因此您可能希望默认使用 HEAD,但如果它抛出 405,您可能会回退到该域的 GET。或者,也许您想为每个请求先尝试 HEAD;YMMV。

如果服务器需要 GET 并且您想减少网络流量,您可以尝试执行条件 GET 和/或部分 GET(参见例如RFC2616)。我从来没有尝试过用 WebRequest 做这些,但我认为它可以让你添加自定义的传出 HTTP 标头,所以你应该能够做到。

另外,不要忘记,如果你正在编写一个蜘蛛(你显然是),你应该尊重服务器的 robots.txt,并且将你的请求限制为每两秒一个请求也是有礼貌的,所以你不要在服务器上划线。

于 2011-03-18T16:02:54.217 回答