【问题标题】:Download File with JSON response as redirection via WebRequest通过 WebRequest 下载带有 JSON 响应的文件作为重定向
【发布时间】:2021-09-17 19:54:58
【问题描述】:

我正在努力寻找一种通过 WebRequest 下载文件的方法。
API 非常简单。所以我有例如以下地址:
https://eprel.ec.europa.eu/api/products/tyres/381324/labels?format=PDF
在这种情况下,浏览器中会显示一个标签。

使用/labels我可以下载一个压缩包。
使用/labels?noDirect=true&format=PDF,响应将是一个200 OK,其内容包含资源的URL (\{address:label or fiche URL})。

附上代码:

Dim request As WebRequest = WebRequest.Create("https://eprel.ec.europa.eu/api/products/tyres/381324/labels?noRedirect=true&format=PDF")
request.Credentials = CredentialCache.DefaultCredentials

Dim response As WebResponse = request.GetResponse()
Console.WriteLine(CType(response, HttpWebResponse).StatusDescription)
Console.WriteLine(response)

Using dataStream As Stream = response.GetResponseStream()
    Dim reader As New StreamReader(dataStream)
    Dim responsefromServer As String = reader.ReadToEnd()
    Console.WriteLine(responsefromServer)
End Using

我得到了 OK 响应,但没有下载标签的 URL。
此外,如果我只使用/labels?format=PDF,我将无法保护显示的 PDF。

我也尝试过 Selenium,但这个解决方案速度很慢。所以我更愿意坚持使用 WebRequest。

也许有人可以帮忙。

【问题讨论】:

    标签: json vb.net pdf download system.net.httpwebrequest


    【解决方案1】:

    API 有一个 2 向响应,基于请求的 URI:

    注意:这是一个二进制文件,不能使用StreamReader读取二进制数据。


    这里有两种方法可以将您的 PDF 文件下载为字节数组。
    GetPDFResourceAsync() 以查询的形式获取 Uri,获取响应,然后调用第二种方法,GetPDFResourceDirectAsync() ,传递从服务器接收到的WebResponse.ResourceUri

    如果你想使用查询URI,调用GetPDFResourceAsync(),如果你想使用直接资源Uri,调用GetPDFResourceDirectAsync()

    InitializeWebRequest() 方法是一个初始化 HttpWebRequest 的实用方法。没有它,GetPDFResourceAsync() 将无法工作,因为服务器需要一个 User-Agent 标头集和一个压缩方法(否则你会得到垃圾)。

    现在,这些方法返回一个字节数组(PDF 文件数据)。
    您可以使用File.WriteAllBytes() 方法将其存储到光盘。例如:

    ' Indirect method, using a URI query
    Dim pdfBytes = Await GetPDFResourceAsync(New Uri("https://eprel.ec.europa.eu/api/products/tyres/381324/labels?format=PDF"))
    ' Direct method, using a resource URI
    Dim pdfBytes = Await GetPDFResourceDirectAsync(New Uri("https://eprel.ec.europa.eu/label/Label_381324.pdf"))
    
    Dim pdfFilePath = Path.Combine("[Some Directory]", "Label381324.pdf")
    File.WriteAllBytes(pdfFilePath, pdfBytes)
    

    工作方法
    如果您不想/不能使用async 方法,只需从所有位置(包括方法名称)删除asyncawait,您将拥有同步代码。

    Public Async Function GetPDFResourceAsync(resourceUri As Uri) As Task(Of Byte())
        Dim request = WebRequest.CreateHttp(resourceUri)
        InitializeWebRequest(request)
        Using locResponse As HttpWebResponse = DirectCast(Await request.GetResponseAsync(), HttpWebResponse)
            If locResponse.StatusCode = HttpStatusCode.OK Then
                Return Await GetPDFResourceDirect(locResponse.ResponseUri)
            Else
                Return Nothing
            End If
        End Using
    End Function
    
    Public Async Function GetPDFResourceDirectAsync(resourceUri As Uri) As Task(Of Byte())
        Dim request = WebRequest.CreateHttp(resourceUri)
        InitializeWebRequest(request)
    
        Dim buffersize As Integer = 132072
        Dim buffer As Byte() = New Byte(buffersize - 1) {}
    
        Dim dataResponse = DirectCast(Await request.GetResponseAsync(), HttpWebResponse)
        If dataResponse.StatusCode = HttpStatusCode.OK Then
            Using responseStream As Stream = dataResponse.GetResponseStream(),
                mStream As MemoryStream = New MemoryStream()
                Dim read As Integer = 0
                Do
                    read = Await responseStream.ReadAsync(buffer, 0, buffer.Length)
                    Await mStream.WriteAsync(buffer, 0, read)
                Loop While read > 0
                Return mStream.ToArray()
            End Using
        End If
        Return Nothing 
    End Function
    
    Private Sub InitializeWebRequest(request As HttpWebRequest)
        request.UserAgent = "Mozilla/5.0 (Windows NT 10; WOW64; Trident/7.0; rv:11.0) like Gecko"
        request.AutomaticDecompression = DecompressionMethods.GZip Or DecompressionMethods.Deflate
        request.Headers.Add(HttpRequestHeader.AcceptEncoding, "gzip, deflate;q=0.8")
        request.Headers.Add(HttpRequestHeader.CacheControl, "no-cache")
    End Sub
    

    【讨论】:

      猜你喜欢
      • 2012-05-24
      • 1970-01-01
      • 2011-10-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-10-22
      • 2011-03-30
      相关资源
      最近更新 更多