Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/excel/28.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/amazon-s3/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
带Excel internet explorer的vba不使用新打开的getelemtsbytagname选项卡_Vba_Excel_Internet Explorer_Dom_Web Scraping - Fatal编程技术网

带Excel internet explorer的vba不使用新打开的getelemtsbytagname选项卡

带Excel internet explorer的vba不使用新打开的getelemtsbytagname选项卡,vba,excel,internet-explorer,dom,web-scraping,Vba,Excel,Internet Explorer,Dom,Web Scraping,我在Microsoft Excel中创建了VBA代码。 我想让代码做的是: 去一个网站 点击网站上的链接 转到新打开的选项卡,然后单击新选项卡上的下载 然后返回根目录/第一页,单击下一页并单击下载 重复此操作,直到单击并下载所有根页面链接 我有下面的代码,类似的工作。它使用internet explorer,因为该网站与google chrome不兼容,不过如果这样效果更好的话,我会试试 代码会导航,会打开选项卡。。。这段代码没有做的是开始使用来自新页面/选项卡的数据,所有元素都来自根页面。我尝

我在Microsoft Excel中创建了VBA代码。 我想让代码做的是:

  • 去一个网站
  • 点击网站上的链接
  • 转到新打开的选项卡,然后单击新选项卡上的下载
  • 然后返回根目录/第一页,单击下一页并单击下载
  • 重复此操作,直到单击并下载所有根页面链接
  • 我有下面的代码,类似的工作。它使用internet explorer,因为该网站与google chrome不兼容,不过如果这样效果更好的话,我会试试

    代码会导航,会打开选项卡。。。这段代码没有做的是开始使用来自新页面/选项卡的数据,所有元素都来自根页面。我尝试创建一个新的IE实例,选择by
    item(1)
    。我不确定需要做什么才能使
    instancehyperlinks
    引用新创建的选项卡。仅供参考,由于根站点的编写方式,数据出现在一个新选项卡中,我无法控制任何HTML

    代码如下:

    Sub-getalllinks()
    模糊的物体
    设置ie=CreateObject(“InternetExplorer.Application”)
    可见=真实
    url_name=“123.123.123.123”
    ie.url\u名称
    做
    多芬特
    循环直到ie.readystate=4'等待直到完全加载
    设置allhyperlinks=ie.document.getelementsbytagname(“A”)
    对于所有超链接中的每个超链接
    如果hyper_link.Title=“查看主题”,则
    超链接。点击
    做
    多芬特
    循环直到ie.readystate=4'等待直到完全加载
    Set instancehyperlinks=ie.document.getelementsbytagname(“A”)
    对于instancehyperlinks中的每个超链接页面
    如果hyper_linkPage.Title=“下载”,则
    超链接页面。单击
    如果结束
    下一个
    如果结束
    下一个
    端接头
    
    好的,我以前遇到过这个问题,并且在不使用任何第三方工具(如selenium)的情况下解决了它。在我得到答案之前,让我给你一个建议:使用VBA自动化IE是一个严重的问题,如果可能的话,我会寻找其他途径

    免责声明:我从其他来源找到并修改了很多代码,由于许多原因,我现在无法找到这些代码的源代码,如果我找到它们,我将在以后添加它们

    好的,首先您需要找到您的窗口,创建一个新模块,将其称为“modWindowsAPI”,并将其添加到其中,这将允许您的脚本连接到必要的windows API中,不仅可以找到窗口,还可以下载:

    Option Explicit
    
    Public Declare Sub Sleep Lib "kernel32" _
        (ByVal dwMilliseconds As Long)
    
    Public Declare Function FindWindow Lib "user32" Alias "FindWindowA" _
        (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
    
    Public Declare Function FindWindowEx Lib "user32" Alias "FindWindowExA" _
        (ByVal hWnd1 As Long, ByVal hWnd2 As Long, ByVal lpsz1 As String, ByVal lpsz2 As String) As Long
    
    Public Declare Function SetForegroundWindow Lib "user32" _
        (ByVal hWnd As Long) As Long
    
    Public Declare Function SendMessage Lib "user32" Alias "SendMessageA" _
        (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
    
    Public Declare Function SendMessageByString Lib "user32" Alias "SendMessageA" _
        (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As String) As Long
    
    Public Declare Function PostMessage Lib "user32" Alias "PostMessageA" _
        (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
    
    Public Declare Sub keybd_event Lib "user32" _
        (ByVal bVk As Byte, ByVal bScan As Byte, ByVal dwFlags As Long, ByVal dwExtraInfo As Long)
    
    Public Const BM_CLICK = &HF5
    Public Const WM_SETTEXT = &HC
    Public Const WM_GETTEXT = &HD
    Public Const WM_GETTEXTLENGTH = &HE
    
    Public Const VK_KEYDOWN = &H0
    Public Const VK_KEYUP = &H2
    Public Const VK_CONTROL = &H11
    
    这里有两种锁定窗口的方法(据我所知,可能还有更多),通过URL或窗口标题查找

    通过URL查找窗口: 创建函数GetOpenIEByTitle:

    Function GetOpenIEByTitle(i_Title As String, Optional ByVal i_ExactMatch As Boolean = True) As SHDocVw.InternetExplorer
        Dim windowMatched As Boolean
        Dim e_title As String
        windowMatched = False
        Dim windowTimeout As Integer
        windowTimeout = 0
    
        Do Until windowMatched = True Or windowTimeout = 10
            If i_ExactMatch = False Then i_Title = "*" & i_Title & "*"
            'ignore errors when accessing the document property
            On Error Resume Next
            'loop over all Shell-Windows
            For Each GetOpenIEByTitle In objShellWindows
                'if the document is of type HTMLDocument, it is an IE window
                If TypeName(GetOpenIEByTitle.Document) = "HTMLDocument" Then
                'check the title
                    If GetOpenIEByTitle.Document.Title Like i_Title Then
                        'leave and set boolean as true, we found the right window
                        windowMatched = True
                        Sleep 600
                        Exit Function
                    End If
                End If
            Next
        windowTimeout = windowTimeout + 1
        Loop
    End Function
    
    通过URL查找窗口: 创建名为GetOpenIEByURL的函数

    Function GetOpenIEByURL(ByVal i_URL As String) As SHDocVw.InternetExplorer
        Dim urlMatched As Boolean
        urlMatched = False
        Dim urlTimeout As Integer
        urlTimeout = 0
        Do Until urlMatched = True Or urlTimeout = 30
    
            Dim objShellWindows As New SHDocVw.ShellWindows
    
            'ignore errors when accessing the document property
            On Error Resume Next
            'loop over all Shell-Windows
            For Each GetOpenIEByURL In objShellWindows
                'if the document is of type HTMLDocument, it is an IE window
                If TypeName(GetOpenIEByURL.Document) = "HTMLDocument" Then
                'check the URL
                    If GetOpenIEByURL.Document.URL = i_URL Then
                        'leave, we found the right window
                        urlMatched = True
                        Exit Function
                    End If
                End If
            Next
    
        urlTimeout = urlTimeout + 1
        Loop
    End Function
    
    总结 您正处于需要多个IE对象的正确路径上,每个活动窗口都需要它自己的对象,如果您关闭它并转到下一个,您可以重用同一个对象

    调用上述方法之一,如下所示:

    Set ieAppChild = GetOpenIEByTitle("Some Title", False)
    Set ieAppChild = GetOpenIEByURL("https://127.0.0.1")
    
    编辑:忘记提及何时准备关闭IE窗口以移动到下一个窗口别忘了调用ieAppChild。退出并且在重用之前不必将IE子对象设置为nothing,但是,这不是最佳做法

    最后是查找下载窗口并单击保存的功能:

    Function SaveAs()
        Dim hWnd As Long
    
        Dim timeout As Date
    
        'Debug.Print "File_Download_Click_Save"
    
        'Find the File Download window, waiting a maximum of 30 seconds for it to appear
    
        timeout = Now + TimeValue("00:00:30")
    
        Do
            hWnd = FindWindow("#32770", "File Download")
            DoEvents
            Sleep 200
        Loop Until hWnd Or Now > timeout
    
        'Debug.Print "   File Download window "; Hex(hWnd)
        If hWnd Then
            'Find the child Save button
            hWnd = FindWindowEx(hWnd, 0, "Button", "&Save")
            'Debug.Print "   Save button "; Hex(hWnd)
        End If
    
    
        If hWnd Then
    
            'Click the Save button
            SetForegroundWindow (hWnd)
            Sleep 600  'this sleep is required and 600 miiliseconds seems to be the minimum that works
            SendMessage hWnd, BM_CLICK, 0, 0
        End If
    End Function
    
    谢谢用户1090660 我解决这个问题的方法是将这个脚本分为两步,首先我将第一页中的所有链接收集到excel表格中 关闭internet explorer 然后为excel工作表中的每个链接重新打开internet explorer 然后我在正确的页面上,可以挖掘数据。 我的方式不如你的方式优雅或可扩展但它很有效, 谢谢你的回答。
    马丁无法重现这个问题。无法访问网站
    123.123.123.123
    。我们无法测试URL,并且没有可使用的HTML。我也看不到上面的窗口查找代码。我建议您研究selenium basic,也许在那里可以很容易地找到选项卡和切换。请共享根网页HTML内容。或者至少在
    hyper\u链接之前添加行
    Debug.Print hyper\u link.outerHtml:Stop
    。单击
    ,并共享即时窗口的输出。检查是否存在,您可以将其删除,然后单击。该网页是安全的,没有用户名和密码我无法访问。如果我登录,我可以通过VBA访问它。感谢用户1090660,我解决它的方法是将它设置为两步脚本,首先我将第一页中的所有链接收集到excel工作表中关闭internet explorer,然后为excel工作表中的每个链接重新打开internet explorer,然后我进入正确的页面并可以挖掘数据。我的方式远不如你的方式优雅或可扩展,但它很有效,谢谢你的回答。马丁不确定这是否真的有必要。您可以将链接存储在节点列表或集合中,并在其上循环。使用现有的IE实例,只需导航到从循环中的当前项(元素)提取的新链接。没错,但当您不确定如何解决问题并开始尝试时,您知道它是什么样子。新的工作表很好,我可以阅读,所以我继续。。。。谢谢你的主意。嗨,我不是故意说粗话的。很抱歉这是一个有用的观察结果。不用担心,我认为它是有用的,马丁