【问题标题】:Using VBA to navigate web page/ maniuplate IE via Access使用 VBA 浏览网页/通过 Access 操作 IE
【发布时间】:2015-04-15 20:47:11
【问题描述】:

你好 StackOverflow 社区,

我有一个关于使用 Access VBA 操作 IE 的问题。

基本上,我正在尝试编写将使用 IE 打开特定网页的代码,在该页面中搜索特定链接(目标链接的名称将取决于用户的情况),导航到新页面以编程方式单击该链接,然后通过在生成的新页面上查找特定链接/元素来重复该过程。

最终目标链接的显示文本将始终相同,但它所在的页面在每种情况下都会有所不同。

我的问题是以编程方式在二级页面中搜索驻留在那里的元素...我的结果一直只给我来自一级页面的元素,即使在浏览器加载了新链接之后也是如此。

抱歉,如果到目前为止我在描述问题的上下文方面做得不好。

我的代码基本上如下:

Dim ie As Object, ieDoc As HTMLDocument

Set ie = CreateObject("InternetExplorer.Application")
ie.Visible = True

strHTML = "http://targetsite.com/first-level_page"

ie.navigate strHTML

'wait for browser
While ie.ReadyState <> READYSTATE_COMPLETE
DoEvents
Wend


'define first-level target link and search for it and then "click" it

Dim i As Integer
Dim txt As String, link As String, p As String

Set ieDoc = ie.Document

txt = "First-Level Target"
    Do Until link = txt Or i >= 1000
    i = i + 1
    link = ieDoc.Links(i).outerText
Loop

'I know the above loop is not exactly ideal in its current form, but it does give me a working first attempt at the functionality I'm trying to build.    

ieDoc.Links(i).Click

到目前为止,一切都很好。上面的代码按预期工作。在所有情况下,它都能正确导航到所需的二级页面。我出错的地方是当我尝试在二级页面中搜索最终目标元素时:

'wait for browser
While ie.ReadyState <> READYSTATE_COMPLETE
DoEvents
Wend

'Search for final target element (which always has the same name and anchor text on all second-level pages)
ieDoc.getElementsByName("final-target-name").Item.Click

如果我尝试在第一级页面上使用上面的行(基于 .getElementsByName),它就可以正常工作。但是一旦我导航到任何二级页面,它就什么也不做。我还尝试将其替换为上述循环的修改版本,该循环在第一级页面上搜索链接。结果一样。

作为故障排除步骤,我还用 debug.print 命令替换了该行,以简单地命名二级页面上的所有元素,而这总是返回第一页中的元素名称。

我认为很明显,在我点击第一个链接之后,我无法正确更新或重新定义我的 HTML 文档。我已将 ieDoc 设置为空,然后将其重新设置为 ie.document,但这也不起作用。

希望有一个我完全不知道的简单命令或语法。但是对于我来说,在单击第一个链接后,我无法让 VBA 正确引用页面上存在的 HTML 元素。

提前感谢您的任何建议!

~JQN

【问题讨论】:

  • 如果不进行测试,我可能会建议您查看您的getElementsByName("target") 是否获得了多个链接,其中第一个链接可能未激活。不要使用.Item 访问元素,而是添加一个索引并尝试使用(1)(这将访问获得的第二个元素,即页面的第二级)。
  • 代码放在哪里?我想它在第二级页面?
  • 在导航事件之后,您仍然拥有相同的ieDoc 引用,它指向一个不再加载的页面。完成任何导航后,您需要刷新该引用 Set ieDoc = ie.Document
  • @TimWilliams 抱歉,我在 OP 的倒数第二段中有一点语言错误 :) ...但我尝试重新设置 ie.doc = ie.document ,导航后,但没有成功。我也尝试过在导航之后但在重新设置 ieDoc = ie.document 之前设置 ieDoc = nothing 的附加步骤(我假设完全多余)的情况下这样做。在所有情况下,我都会得到完全相同的行为。
  • @Roman 我已经在我的一个 Access 表单中的按钮的“OnClick”事件中运行了所有这些代码。

标签: html vba internet-explorer ms-access


【解决方案1】:

您需要结合使用@Matteo NNZ 和@TimWilliams

如果您知道元素的“id”名称,则更容易使用 getElementsByName("target")。

如果您不知道“id”,则循环锚元素并搜索正确的文本。这缩小到只有链接或元素。

Set Anchors = IeDoc.getElementsByTagName("a")

然后循环比较 .outertext 或您需要的任何子字段。

@蒂姆威廉姆斯: 您需要加载找到的 URL,然后在循环内设置新加载的 IeDoc。将“ie”对象设置为新的“ie”加载页面,否则“ie”对象将正确地保持加载的第一个页面。 当你找到你的链接时,你需要像你已经完成的那样加载新页面。

'' throw away the first page loaded.
ie = nothing 
IeDoc = nothing

'' Set the new page loaded.
ie.navigate newHTML

'wait for browser
While ie.ReadyState <> READYSTATE_COMPLETE
DoEvents
Wend

Set IeDoc = ie.Document

对第二页重复上述过程

以下是有关“在 vba 中解析 HTML”的其他一些资源: http://www.ozgrid.com/forum/showthread.php?t=184695 Parse HTML content in VBA

【讨论】:

    【解决方案2】:

    在这种特殊情况下,我能够解决 HTML 方面的问题,尽管我认为一般来说 @Matteo NNZ 、 @TimWilliams 和 @durbo 发布的答案仅适用于 Access/ VBA 方面的问题。再次感谢所有花时间回复的人!

    【讨论】:

    • 约翰,这不是你问题的答案。通过提供有关您如何解决问题的正确答案来帮助社区。它是关于帮助在您解决类似问题后出现的人。
    猜你喜欢
    • 2015-04-30
    • 2020-02-13
    • 1970-01-01
    • 1970-01-01
    • 2019-02-15
    • 1970-01-01
    • 1970-01-01
    • 2014-04-16
    • 2011-02-09
    相关资源
    最近更新 更多