带Excel internet explorer的vba不使用新打开的getelemtsbytagname选项卡
我在Microsoft Excel中创建了VBA代码。 我想让代码做的是:带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不兼容,不过如果这样效果更好的话,我会试试 代码会导航,会打开选项卡。。。这段代码没有做的是开始使用来自新页面/选项卡的数据,所有元素都来自根页面。我尝
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实例,只需导航到从循环中的当前项(元素)提取的新链接。没错,但当您不确定如何解决问题并开始尝试时,您知道它是什么样子。新的工作表很好,我可以阅读,所以我继续。。。。谢谢你的主意。嗨,我不是故意说粗话的。很抱歉这是一个有用的观察结果。不用担心,我认为它是有用的,马丁