首页 > 解决方案 > 循环浏览网站链接并获取 PDF 到我的电脑

问题描述

本主题与循环链接和下载 PDF 相关

我正在尝试将我当前的 VBA 代码转换为 VBScript。我已经明白我必须删除变量类型(As ... Dim 语句的一部分)并使用 CreatObject 来获取这些对象,否则一切都应该按原样移植。DoEvents 也必须替换为 Wscript.sleep 之类的东西。

我想出了一些问题。目前在运行 VBS 文件时,我收到一条错误消息,提示“需要对象:'MSHTML'”。指向第 65 行,我有Set hDoc = MSHTML.HTMLDocument. 我试图在谷歌上搜索,但对这个没有任何帮助。

我应该如何处理这个?

DownloadFiles("https://www.nordicwater.com/products/waste-water/")

Sub DownloadFiles(p_sURL)
    Set xHttp = CreateObject("Microsoft.XMLHTTP")
    Dim xHttp 
    Dim hDoc
    Dim Anchors 
    Dim Anchor 
    Dim sPath
    Dim wholeURL

    Dim internet
    Dim internetdata
    Dim internetlink
    Dim internetinnerlink 
    Dim arrLinks 
    Dim sLink 
    Dim iLinkCount 
    Dim iCounter 
    Dim sLinks

    Set internet = CreateObject("InternetExplorer.Application")
    internet.Visible = False
    internet.navigate (p_sURL)

        Do Until internet.ReadyState = 4
        Wscript.Sleep 100
        Loop

        Set internetdata = internet.document
        Set internetlink = internetdata.getElementsByTagName("a")

        i = 1

        For Each internetinnerlink In internetlink
            If Left(internetinnerlink, 36) = "https://www.nordicwater.com/product/" Then

                If sLinks <> "" Then sLinks = sLinks & vbCrLf
                sLinks = sLinks & internetinnerlink.href
                i = i + 1

            Else
            End If

    Next

    wholeURL = "https://www.nordicwater.com/"
    sPath = "C:\temp\"

    arrLinks = Split(sLinks, vbCrLf)
    iLinkCount = UBound(arrLinks) + 1

    For iCounter = 1 To iLinkCount
    sLink = arrLinks(iCounter - 1)
        'Get the directory listing
        xHttp.Open "GET", sLink
        xHttp.send

        'Wait for the page to load
        Do Until xHttp.ReadyState = 4
        Wscript.Sleep 100
        Loop

        'Put the page in an HTML document
        Set hDoc = MSHTML.HTMLDocument
        hDoc.body.innerHTML = xHttp.responseText

        'Loop through the hyperlinks on the directory listing
        Set Anchors = hDoc.getElementsByTagName("a")

        For Each Anchor In Anchors

            'test the pathname to see if it matches your pattern
            If Anchor.pathname Like "*.pdf" Then

                xHttp.Open "GET", wholeURL & Anchor.pathname, False
                xHttp.send

                With CreateObject("Adodb.Stream")
                    .Type = 1
                    .Open
                    .write xHttp.responseBody
                    .SaveToFile sPath & getName(wholeURL & Anchor.pathname), 2 '//overwrite
                End With

            End If

        Next

    Next

End Sub

功能:

Function getName(pf)
    getName = Split(pf, "/")(UBound(Split(pf, "/")))
End Function

标签: web-scrapingvbscriptweb-crawler

解决方案


代替Set hDoc = MSHTML.HTMLDocument, 使用:

Set hDoc = CreateObject("htmlfile")

在 VBA/VB6 中,您可以指定变量和对象类型,但不能使用 VBScript。您必须使用CreateObject(或GetObjectGetObject 函数)来实例化对象,如MSHTML.HTMLDocument, Microsoft.XMLHTTP,等,而不是使用例如InternetExplorer.Application声明那些对象。Dim objIE As InternetExplorer.Application

另一个变化:

If Anchor.pathname Like "*.pdf" Then

可以使用StrComp 函数编写:

If StrComp(Right(Anchor.pathname, 4), ".pdf", vbTextCompare) = 0 Then

或使用InStr 函数

If InStr(Anchor.pathname, ".pdf") > 0 Then

此外,在您的 sub 开始时,您执行以下操作:

Set xHttp = CreateObject("Microsoft.XMLHTTP")
Dim xHttp 

您应该在分配值或对象之前声明您的变量。在 VBScript 中这是非常轻松的,您的代码将可以工作,因为 VBScript 会为您创建未定义的变量,但Dim在使用它们之前对您的变量进行很好的实践。

Wscript.sleep命令外,您的 VBScript 代码将在 VB6/VBA 中工作,因此您可以在 VB6 或 VBA 应用程序(如 Excel)中调试脚本。


推荐阅读