【问题标题】:Download URL Contents Directly into String (VB6) WITHOUT Saving to Disk将 URL 内容直接下载到字符串 (VB6) 中而不保存到磁盘
【发布时间】:2012-06-13 16:47:12
【问题描述】:

基本上,我想将特定 URL 的内容(基本上,只是字符串形式的 HTML 代码)下载到我的 VB6 字符串变量中。但是,有一些条件。

我知道 URLDownloadToFile 函数 - 但是,这需要您将下载的文件/HTML 保存到磁盘上的文件位置,然后才能将其读入字符串变量,这对我来说不是一个选项,我不想要这样做。

另一件事是,如果我需要使用外部库,它必须已经从 XP 及更高版本的所有 Windows 版本中提供,我不能使用我需要运送、打包和分发的控件或库,即使它是免费的,这不是一个选项,我不想这样做。因此,我不能使用 MSINET.OCX(Internet 传输)控件的 .OpenURL() 函数(它只是将内容返回到字符串中),因为它不随 Windows 提供。

有没有办法通过 Windows API、URLMON 或其他预加载到或随 Windows 提供的东西来做到这一点,或者完全在 VB6 (SP6) 中做到这一点?

如果是这样,我将不胜感激,因为即使经过一小时的谷歌搜索,我发现的唯一示例是对 URLDownloadToFile 的引用(这需要在将啤酒放入字符串之前保存在磁盘上)和 MsInet.OpenURL(这要求我发布和分发 MSINET.OCX,我不能也不想这样做)。

肯定有一种优雅的方式可以做到这一点吗?我可以在 VB.NET 中毫无问题地做到这一点,但显然没有 VB6 中的 .NET 框架的奢华——有什么想法吗?

更新:

我发现了这个:http://www.freevbcode.com/ShowCode.asp?ID=1252 但是它说显示的功能可能不会返回整个 页面和指向 Microsoft 错误报告或 kb 文章的链接 这。另外,我知道这是基于 wininet.dll - 我是 想知道 WinInet.dll 打包了哪些版本的 Windows 和? Windows XP 及更高版本?它是否与 Windows 7 和/或 Windows 一起提供 8?

【问题讨论】:

  • 您所链接的代码是针对互联网传输控制中存在的错误的修复;你可以使用它。 (support.microsoft.com/kb/232194) 代码使用的 wininet 堆栈是核心操作系统组件,存在于 Windows 2000 及更高版本中。 (谷歌用于 InternetReadFile 的 msdn 页面,底部会有支持的操作系统版本列表)
  • 您可以使用 MSXML2.XMLHTTP 执行此操作,只需向 URL 发出 GET 请求,然后将 XMLHTTP.responseText 保存到 String 变量中。
  • 内部的AsyncRead方法可用,还有WinHTTP。无需注册的 COM 消除了与部署简单性相关的大多数问题。
  • 我认为没有理由不使用 Internet 传输控件,但还有其他选择,例如致电 WinINet directly
  • @Bob Riemersma 请问,什么是Reg-Free COM?听起来很有趣。

标签: api winapi vba vb6 wininet


【解决方案1】:

这就是我几年前使用 VB6 的方式:

Private Function GetHTMLSource(ByVal sURL As String) As String
Dim xmlHttp As Object
    Set xmlHttp = CreateObject("MSXML2.XmlHttp")
    xmlHttp.Open "GET", sURL, False
    xmlHttp.send
    GetHTMLSource = xmlHttp.responseText
    Set xmlHttp = Nothing
End Function

【讨论】:

  • + 1. 我也推荐 xmlHttp :)
  • 感谢 heaps antagony,这肯定对许多人有用。赞成。
【解决方案2】:

另一种方法是使用 Internet Explorer。

Dim ex As InternetExplorer
Dim hd As HTMLDocument
Dim s As String

Set ex = New InternetExplorer

With ex
    .Navigate "http://donttrack.us/"
    .Visible = 1
    Set hd = .Document
    s = hd.body.innerText ' assuming you just want the text
    's = hd.body.innerHTML ' if you want the HTML
End With

编辑:要使上述早期绑定起作用,您需要设置对“Microsoft Internet 控件”和“Microsoft HTML 对象库”的引用(工具 > 引用)。您也可以使用后期绑定,但老实说,我忘记了正确的类名是什么;也许聪明的人会编辑这个答案:-)

【讨论】:

  • + 1 另一种好方法。您可能想切换到后期绑定或提及需要将引用添加到 IE?
  • 感谢伙计,这是另一个好主意,尽管我在网络浏览器控制方面有多年经验,但出于某种原因,我什至从未想到过 :)。还想补充一点,您使用 Internet Explorer 而不是 WebBrowser 控件的方法是一个更好的主意,因为 WB 控件将根据您安装的版本使用 IE7 或 IE4,并且不使用最新安装的 IE 版本。但是,当您直接使用 IE 时,您总是使用客户端计算机上安装的最新 IE 版本。再次感谢,点赞。
【解决方案3】:

如果您想使用纯 VB 而不是 IE 来执行此操作,那么您可以利用 VB UserControl 的一个很少使用的功能 - 异步属性。

创建一个新的 UserControl,并将其命名为 UrlDownloader。将 InvisibleAtRuntime 属性设置为 True。添加以下代码:

Option Explicit

Private Const m_ksProp_Data         As String = "Data"

Private m_bAsync                    As Boolean
Private m_sURL                      As String

Public Event AsyncReadProgress(ByRef the_abytData() As Byte)
Public Event AsyncReadComplete(ByRef the_abytData() As Byte)

Public Property Let Async(ByVal the_bValue As Boolean)
    m_bAsync = the_bValue
End Property

Public Property Get Async() As Boolean
    Async = m_bAsync
End Property

Public Property Let URL(ByVal the_sValue As String)
    m_sURL = the_sValue
End Property

Public Property Get URL() As String
    URL = m_sURL
End Property

Public Sub Download()

    UserControl.AsyncRead m_sURL, vbAsyncTypeByteArray, m_ksProp_Data, IIf(m_bAsync, 0&, vbAsyncReadSynchronousDownload)

End Sub

Private Sub UserControl_AsyncReadComplete(AsyncProp As AsyncProperty)

    If AsyncProp.PropertyName = m_ksProp_Data Then
        RaiseEvent AsyncReadComplete(AsyncProp.Value)
    End If

End Sub

Private Sub UserControl_AsyncReadProgress(AsyncProp As AsyncProperty)

    If AsyncProp.PropertyName = m_ksProp_Data Then
        Select Case AsyncProp.StatusCode
        Case vbAsyncStatusCodeBeginDownloadData, vbAsyncStatusCodeDownloadingData, vbAsyncStatusCodeEndDownloadData
            RaiseEvent AsyncReadProgress(AsyncProp.Value)
        End Select
    End If

End Sub

要使用此控件,请将其粘贴在表单上并使用以下代码:

Option Explicit

Private Sub Command1_Click()

    XDownload1.Async = False
    XDownload1.URL = "http://www.google.co.uk"
    XDownload1.Download

End Sub

Private Sub XDownload1_AsyncReadProgress(the_abytData() As Byte)

    Debug.Print StrConv(the_abytData(), vbUnicode)

End Sub

可以这么说,您可以根据自己的喜好对其进行自定义。它可以告诉(使用 AyncProp 对象)文件是否被缓存,以及其他有用的信息。它甚至有一个特殊的模式,您可以在其中下载 GIF、JPG 和 BMP 文件并将它们作为 StdPicture 对象返回!

【讨论】:

  • 我只是想说,这很有趣,在这里我想我对 VB6 了如指掌,而且我知道 - 你用这个很棒的解决方案打了我。只是一个问题,我可以将其作为用户控制文件包含在我的项目中,对吗?不必编译和引用它作为 dll 或 ocx? (再次感谢,点赞)
  • 是的,没错。 UserControl 可以设置为 Public = False。请注意 - 尽管我在上面提到过,这可能依赖于 Internet Explorer 附带的组件。如果您查看 VB6 发行说明,它至少需要 Internet Explorer 5。它所指的缓存可能是 Internet 临时文件。也许我应该说“无引用”:-)。
  • 我也觉得这很有趣,但我无法让它像现在这样工作。它在RaiseEvent 行的AsyncProp.Value 上引发类型不匹配错误。为了让它工作,我必须将事件参数更改为变体并删除数组括号,无论是在那里还是在Debug.Print 行中。不过当时它起作用了,所以+1非常好。 :-)
  • 嗯,这很奇怪。我从上面的页面中获取了代码,并按照我自己的说明进行操作 - 但它似乎无需修改即可工作。
  • 好吧,我刚刚又试了一次,这次在 XP VM 机器上我保持更新以进行测试,结果完全一样。我们可以运行稍微不同版本的 VBRUN 吗?我正在使用 MSVBVM60.dll 版本 6.00.98.15 运行 VB6/SP6
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-10-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-08-31
  • 2012-05-13
  • 2014-10-04
相关资源
最近更新 更多