通过身份验证从网站自动下载图片,第二部分

时间:2015-02-05 07:53:18

标签: .net vb.net http cookies httpwebrequest

此问题源于另一个问题:Automate picture downloads from website with authentication 我问过如何从需要登录的特定网站下载图片。

同一家公司有两个网站,cgwallpapers.comgamewallpapers.com,因为在回答其他问题的用户的帮助下,我终于如何自动下载其中一个网站,我无法在gamewallpapers.com网站上重现相同的步骤。

由于我对请求的经验不足,我可能会说错了,所以如果帮助者/专家有时间我真的建议验证参数和其他我要去的东西说的就像我说或不是,正如我所说,我可能是错的。

在cgwallpapers.com中,我基本上设置了这样的查询来下载壁纸:

http://www.cgmewallpapers.com/members/getwallpaper.php?id=100&res=1920x1080

但我发现在gamewallpapers.com中我无法使用相同的帖子数据,因为它似乎是这样的:

http://www.gamewallpapers.com/members/getwallpaper.php?wallpaper=wallpaper_ancient_space_01_1920x1080.jpg&keystr=1423106012&retry=

在cgwallpapers中更容易因为我可以使用具有特定壁纸分辨率的ID的增量for循环,但是使用gamewallpapers.com网站我无法弄清楚如何自动化壁纸下载,它似乎需要一个如果我没有错,治疗会完全不同。

所以,我不知道该尝试什么,甚至不知道怎么做。

登录gamewallpapers.com后,这是我尝试下载壁纸的方式,当然这不起作用,因为我没有使用正确的查询,但此代码适用于cgwallpaper.com网站所以我会展示它是否可以为某些事情提供帮助:

注意:WallpaperInfo是一个不相关的对象,我用它来返回下载的壁纸图像流,它是很多代码所以我跳过它。

''' <summary>
''' Tries to download the specified wallpaper from GameWallpapers server.
''' </summary>
''' <param name="id">The wallpaper id.</param>
''' <param name="res">The wallpaper resolution.</param>
''' <param name="cookieCollection">The cookie collection.</param>
''' <returns>A <see cref="WallpaperInfo"/> instance containing the wallpaper info and the image stream.</returns>
Private Function GetWallpaperMethod(ByVal id As String,
                                    ByVal res As String,
                                    ByRef cookieCollection As CookieCollection) As WallpaperInfo

    Dim request As HttpWebRequest
    Dim url As String = String.Format("http://www.gamewallpapers.com/members/getwallpaper.php?id={0}&res={1}", id, res)
    Dim contentDisposition As String
    Dim webResponse As WebResponse = Nothing
    Dim responseStream As Stream = Nothing
    Dim imageStream As MemoryStream = Nothing
    Dim wallInfo As WallpaperInfo = Nothing

    Try
        request = DirectCast(HttpWebRequest.Create(url), HttpWebRequest)
        With request
            .Method = "GET"
            .Headers.Add("Accept-Language", "en-US,en;q=0.5")
            .Headers.Add("Accept-Encoding", "gzip, deflate")
            .Headers.Add("Keep-Alive", "300")
            .Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"
            .AllowAutoRedirect = False
            .UserAgent = "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:35.0) Gecko/20100101 Firefox/35.0"
            .KeepAlive = True
        End With

        If cookieCollection IsNot Nothing Then
            ' Pass cookie info so that we remain logged in.
            request.CookieContainer = Me.SetCookieContainer(url, cookieCollection)
        End If

        webResponse = request.GetResponse

        Using webResponse

            contentDisposition = CType(webResponse, HttpWebResponse).Headers("Content-Disposition")

            If Not String.IsNullOrEmpty(contentDisposition) Then ' There is an image to download.

                Dim filename As String = contentDisposition.Substring(contentDisposition.IndexOf("=") + "=".Length).
                                         TrimStart(" "c).TrimEnd({" "c, ";"c})

                Try
                    imageStream = New MemoryStream
                    responseStream = webResponse.GetResponseStream

                    Using responseStream

                        Dim buffer(2047) As Byte
                        Dim read As Integer

                        Do
                            read = responseStream.Read(buffer, 0, buffer.Length)
                            imageStream.Write(buffer, 0, read)
                        Loop Until read = 0

                        responseStream.Close()

                    End Using

                Catch ex As Exception
                    Throw

                End Try

                ' This is the object that I'll return
                ' that I'm storing the url, the wallpaper id,
                ' the wallpaper resolution, the wallpaper filename
                ' and finally the downloaded MemoryStream (the wallpaper image stream)
                wallInfo = New WallpaperInfo(url:=url,
                                             id:=id,
                                             resolution:=res,
                                             filename:=filename,
                                             imageStream:=imageStream)

            End If ' String.IsNullOrEmpty(contentDisposition)

        End Using ' webResponse

    Catch ex As Exception
        Throw

    Finally
        If webResponse IsNot Nothing Then
            webResponse.Close()
        End If
        If responseStream IsNot Nothing Then
            responseStream.Close()
        End If

    End Try

    Return wallInfo

End Function

Private Function SetCookieContainer(ByVal url As String,
                                    ByVal cookieCollection As CookieCollection) As CookieContainer

    Dim cookieContainer As New CookieContainer
    Dim refDate As Date

    For Each oldCookie As Cookie In cookieCollection

        If Not DateTime.TryParse(oldCookie.Value, refDate) Then

            Dim newCookie As New Cookie
            With newCookie
                .Name = oldCookie.Name
                .Value = oldCookie.Value
                .Domain = New Uri(url).Host
                .Secure = False
            End With

            cookieContainer.Add(newCookie)

        End If

    Next oldCookie

    Return cookieContainer

End Function

以下是我试图通过一个示例用法来实现它的完整源代码,我希望它应该如何工作(for循环增加壁纸ID以自动下载),当改变基本URL名称时它非常有用gamewallpapers.comcgwallpapers.com,因为此来源仅适用于cgwallpapers.com,但我只是尝试使用gamewallpapers.com网址:

http://pastebin.com/eyBxHmnJ

2 个答案:

答案 0 :(得分:4)

<强>更新

正如所承诺的那样,我已经提出了一个适当的&#34;使用Telerik Testing Framework解决您对gamewallpapers.com的问题。

您必须将sUsernamesPassword变量更改为您自己的用户名/密码才能成功登录该网站。

您可能想要更改的可选变量:

  • sResolutionString:默认为1920x1080,这是您在原始问题中指定的内容。将此值更改为网站上任何可接受的分辨率值。只是警告我并非100%确定所有图像是否具有相同的分辨率,因此如果没有所需分辨率的图像,更改此值可能会导致某些图像被跳过。
  • sDownloadPath:当前设置为与应用程序exe相同的文件夹。将其更改为您要下载图像的路径。
  • sUserAgent:默认使用适用于Windows 7的Internet Explorer 11的用户代理。由于Telerik测试框架控制着真正的浏览器(在这种情况下,您在PC上安装的IE版本),它使用& #34;实&#34;发送请求时的用户代理。此可变用户代理字符串仅在使用HttpWebRequest下载壁纸时使用,并且默认情况下很可能是不必要的,因为所包含的代码将捕获Telerik使用的用户代理并保存以供以后使用。
  • nMaxSkippedFilesInSuccession:默认设置为10。尝试下载壁纸图像时,应用程序将检查下载目录中是否已存在文件名。如果存在,则不会下载文件,并且会增加跳过计数器。如果跳过计数器达到nMaxSkippedFilesInSuccession的值,则应用程序将停止,因为它假定您已在先前会话中下载了其余文件。 注意:理论上,这个值甚至可以设置为1或2,因为文件名非常独特,因此永远不会重叠。问题是toplist.php页面按日期排序,如果在运行此应用程序的中间,他们会添加x个新图像,然后当您转到下一页时,图像将被移动x。如果x大于nMaxSkippedFilesInSuccession,那么您很可能会发现该应用程序会过早结束,因为您会尝试再次下载大量相同的图像。
  • nCurrentPageID:默认设置为0。列表页面toplist.php接受名为Start的查询字符串参数,该参数告诉页面从哪个索引开始,具体取决于您选择的搜索参数。该列表显示每页24个图像,因此nCurrentPageID变量必须可被24整除,否则您最终可能会跳过图像。根据时间和环境,您可能无法在一个会话中下载所有图像。如果是这种情况,您可以记住您中断了哪个nCurrentPageID并相应地更新此变量,以便下次启动另一个ID(请记住,自从新壁纸添加到网站后,图片可能会被移动列表页面按壁纸日期排序。)

要使用Telerik Testing Framework,您只需安装设置文件,然后添加对ArtOfTest.WebAii.dll的引用。

关于使用测试框架(至少使用Internet Explorer)的一个怪癖是,它不允许您将浏览器作为隐藏进程启动。我已经谈过telerik对此的支持,他们声称虽然像Watin这样的其他网络抓取框架确实支持这个功能,但是不可能这样做(我个人仍然喜欢Watin这个和其他原因但现在已经很老了,因为现在还没有更新2011)。由于在后台运行Web抓取任务而不打扰您使用计算机很好,这个示例启动浏览器最小化(telerik支持),然后使用Windows api调用来隐藏浏览器进程。这有点像黑客,但它很有用,并且在我的经验中运作良好。

在我原来的回答中,我提到您很可能必须通过点击链接并构建下载网址来抓取toplist.php页面,但我能够在不点击除{{{{}之外的任何页面的情况下使其工作1}}。这是唯一可能的,因为壁纸文件名(基本上是您需要下载的ID)部分包含在预览图像中。我最初也认为toplist.php查询字符串参数是某种类型的id&#34; protected&#34;下载但实际上并不需要获得壁纸。

最后要提到的是keystr页面可以按评级或日期排序。评级非常不稳定,随着人们投票选择图像,随时可能发生变化,因此这对于此类工作来说不是一个好的排序方法。我们在这种情况下使用日期,因为它适用于排序,并且应始终使图像的顺序与以前相同,但存在一个小问题:它似乎不允许您按相反的顺序排序。因此,最新图像始终显示在第一页的顶部。这会导致图像在列表中移位,并且很可能会导致您在发生这种情况时重新测试相同的图像。对于cgwallpapers.com,这不是问题,因为新图像将获得新的(更高的)id值,我们可以记住我们中断的最后一个ID并连续测试下一个id以查看是否有新图像。对于gamewallpapers.com,我们总是从pageid 0重新运行并继续运行,直到我们达到一定数量的跳过文件,以便知道自上次下载以来我们何时找到了图像的结尾。

这是代码。如果您有疑问,请告诉我们:

toplist.php

答案 1 :(得分:2)

通常WGET工具可以解决这个问题,并允许您下载网站目录中的所有文件。不幸的是,我尝试了它并没有工作,我不确定它是否因为我不是网站的成员或者图像存储在数据库中。

enter image description here


查看查询字符串我相信他们没有故意使用数字ID(出于安全原因 - 所以人们不能轻易地获得他们网站的webdump),因为字母数字壁纸名称和键盘是必需的:

  

壁纸= <强> wallpaper_ancient_space_01_1920x1080.jpg &安培; keystr = <强> 1423106012 &安培;重试=

如果Wget失败,您需要编写一个screenscraper来下载每个页面上的链接,例如:

System.Net.WebClient.DownloadFile("http://www.gamewallpapers.com/toplist.php","C:\temp\page with links.txt")

您可以通过递增&amp; start查询字符串参数来轻松分页下载所有页面:

http://www.gamewallpapers.com/toplist.php 开始= 24 &安培;行动=去&安培;标题=安培;最大生存周期= 0&安培; latestnr = 0&安培;平台=安培;分辨率=安培; cyberbabes =安培; membersonly2 =&安培;评级= 0&安培; minimumvotes2 = 0&安培;排序=日期

获得图像的所有链接后,您可以使用WebClient或HttpWebRequest下载它们。