如何使用HTTPWebRequest解压缩GZIP / DEFLATE内容

时间:2013-08-14 15:48:28

标签: .net httpwebrequest httpclient

当从Microsoft HTTPClient(3.5及之前的包装器)或HTTPWebResponse(.NET 4.0及更高版本)中读取响应流时,两个实例似乎都开始返回二进制内容。

我们有数百个网络蜘蛛,其中许多使用不同的框架或“一次性”代码。并且他们一个接一个地开始为HTML返回垃圾。我认为这是我们正在触摸和重建DLL的那些。这让我觉得框架中发生了一些变化。

这是我的主要方法:

Public Function PostPage(ByVal URL As String, ByVal enc As Encoding) As String
    Try
        ServicePointManager.ServerCertificateValidationCallback = New RemoteCertificateValidationCallback(AddressOf ValidateCertificate)
        Dim htmlRequest As HttpWebRequest = DirectCast(WebRequest.Create(URL), HttpWebRequest)
        htmlRequest.Headers.Add("Accept-Encoding", "gzip, deflate")
        Dim htmlResponse As HttpWebResponse = DirectCast(htmlRequest.GetResponse(), HttpWebResponse)
        Return New System.IO.StreamReader(htmlResponse.GetResponseStream(), enc).ReadToEnd()
    Catch ex As Exception
        Console.WriteLine("Error: " & ex.Message)
    End Try
    Return ""
End Function

这是非常基本的,我不确定发生了什么,每种类型的编码(包括不指定任何编码)都返回二进制。当我输入http://www.google.com作为URL时,这是一个有效的表示。

2 个答案:

答案 0 :(得分:2)

当您添加Accept-Encoding标头时,您告诉Web服务器:“请发送给我一个使用GZIP或DEFLATE压缩的响应。”

网络服务器尽职地返回此类响应,您的客户端获取压缩内容。如果要解压缩该内容,则必须手动执行此操作,如果您的对象不支持自动解压缩。

不是手动添加Accept-Encoding标头,而是告诉.NET执行此操作并代表您自动解压缩响应。

htmlRequest.AutomaticDecompression = DecompressionMethods.Deflate | DecompressionMethods.GZip;

答案 1 :(得分:0)

正如我在问题中所说:相信它是编码,我写了一个循环,循环遍历所有可能的编码,包括UTF8和UTF7,甚至意大利语和其他语言和一切。 (139我认为是)。它将编码名称和HTML结果存储在一个字典中,然后我查看并看到它都是垃圾。

Sub LearnEncoding(ByVal MyURL As String)
    Dim dctResults As New Dictionary(Of String, String)
    For Each objEncoding In System.Text.Encoding.GetEncodings
        If dctResults.ContainsKey(objEncoding.DisplayName) = False Then
            Dim MySpider As New clsWebSpider
            dctResults.Add(objEncoding.DisplayName, MySpider.PostPage(MyURL, objEncoding.GetEncoding))
        End If
    Next
End Sub

经过大量研究和测试后,我发现问题出现在:

Accept-Encoding: gzip, deflate

什么!?!?

默认情况下,它位于MSHTTPClient中,当您从浏览器请求中查看Fiddler中的标头时,自然会出现这种情况。当然,浏览器并不关心垃圾,它们似乎能够解码任何东西。我不写解码器。

因此,对于许多使用MSHTTPClient的蜘蛛,我们调用了DefaultHeaders.AcceptEncoding.Clear(),对于我们的HttpWebRequests,我们刚刚删除了AcceptEncoding的设置行。它们都会再次返回良好的HTML。我研究了框架的变化,但找不到任何解释它的东西。