【问题标题】:Extract data within iframes using VBA code looping problem使用 VBA 代码循环问题在 iframe 中提取数据
【发布时间】:2018-09-30 09:46:13
【问题描述】:

下面的代码运行良好,结果我得到了我需要的值。但是在运行过程结束时,它会在“With .document.getElementById("bm_ann_detail_iframe").contentDocument”这一行显示“Run-time error '424' Object required”。

用于从以下位置提取数据的示例 url 链接: http://www.bursamalaysia.com/market/listed-companies/company-announcements/5927925

http://www.bursamalaysia.com/market/listed-companies/company-announcements/5927809

http://www.bursamalaysia.com/market/listed-companies/company-announcements/5927509

Public Sub GetInfo()
Dim IE As New InternetExplorer, clipboard As Object
With IE
    .Visible = False

    For u = 2 To 100

    .navigate Cells(u, 1).Value

    While .Busy Or .readyState < 4: DoEvents: Wend


    With .document.getElementById("bm_ann_detail_iframe").contentDocument
        ThisWorkbook.Worksheets("Sheet1").Cells(u, 3) = .getElementsByClassName("formContentDataH")(3).innerText
        ThisWorkbook.Worksheets("Sheet1").Cells(u, 4) = .getElementsByClassName("company_name")(0).innerText
        ThisWorkbook.Worksheets("Sheet1").Cells(u, 5) = .getElementsByClassName("formContentDataH")(1).innerText
        ThisWorkbook.Worksheets("Sheet1").Cells(u, 6) = .getElementsByClassName("formContentData")(3).innerText
        ThisWorkbook.Worksheets("Sheet1").Cells(u, 7) = .getElementsByClassName("formContentData")(4).innerText
        ThisWorkbook.Worksheets("Sheet1").Cells(u, 8) = .getElementsByClassName("formContentData")(5).innerText
        ThisWorkbook.Worksheets("Sheet1").Cells(u, 9) = .getElementsByClassName("formContentData")(9).innerText

   End With
   Next u
End With
End Sub

【问题讨论】:

  • 请问哪个 URL 失败了?您提供的 3 工作正常。每个单元格中都有有效的 URL 吗?请参阅我对上一个问题here 的回答以处理此问题。
  • 是的,网址工作正常。我已经得到了我所有的价值观。但每次进程结束时,它都会显示需要运行时错误'424'对象。似乎无法顺利结束。
  • 这似乎意味着您正在尝试访问不再可用的文档,您确定 Cells(100, 1) 有一个有效的 URL 可以使用并且循环停止在这点如预期?如果您已正确循环并获得所有值,则循环不应返回 With .document.getElementById("bm_ann_detail_iframe").contentDocument ,这就是您所说的错误所在,不是吗?
  • url 的数量取决于我从中提取的页面,因此它的数字在 1 到 100 之间变化。如果单元格(100,1)为空白,是否会导致循环停止?我认为这是问题的原因
  • 是的。您需要动态确定循环的结束。将其存储在变量中并循环到该变量。如果您循环到一个空白 URL,那么您会遇到问题,因为没有可使用的文档。在我对你的另一个问题的回答中,我做了一个简单的测试,看看它是否是单元格中的 URL,即 If InStr(links(u), "http") > 0 Then 。在这种情况下,而不是工作表中的单元格,我将单元格的内容放入一个数组中,但原理相同。

标签: excel vba url web-scraping extract


【解决方案1】:

我将建议一个简单的测试,即单元格中有一个"http" 字符串(使用它作为有一个可以使用的 URL 的基础)。我更喜欢这个而不是 IsEmpty 测试。这是为了减少在循环期间尝试访问不存在的页面。您的错误似乎表明该框架在循环期间未定位。因此,可能性包括单元格中没有 URL(从 cmets 看来这是一种可能性)或无效的 URL/不符合预期模式的 URL。

我通过使用 On Error Resume Next 语句来处理后一种可能性。您可能希望调试特定的失败 URL(如果存在),以检查 iframe 在预期时不存在的情况,并确定所需的任何进一步改进。

在 URL 数量不同的情况下,您可以像当前一样使用固定的结束循环,或者动态确定最后一行,例如

Dim lastRow As Long
With ThisWorkbook.Worksheets("Sheet1")
    lastRow = .Cells(.Rows.Count, "A").End(xlUp).Row
End With

然后从

循环
For u = 2 To lastRow

我仍然希望有一个 Instr 测试 "http" 存在。

VBA:

Option Explicit
Public Sub GetInfo()
    Dim IE As New InternetExplorer, u As Long
    With IE
        .Visible = True

        For u = 2 To 100
            If InStr(Cells(u, 1).Value, "http") > 0 Then

                .navigate Cells(u, 1).Value

                While .Busy Or .readyState < 4: DoEvents: Wend
                On Error Resume Next
                With .document.getElementById("bm_ann_detail_iframe").contentDocument
                    ThisWorkbook.Worksheets("Sheet1").Cells(u, 3) = .getElementsByClassName("formContentDataH")(3).innerText
                    ThisWorkbook.Worksheets("Sheet1").Cells(u, 4) = .getElementsByClassName("company_name")(0).innerText
                    ThisWorkbook.Worksheets("Sheet1").Cells(u, 5) = .getElementsByClassName("formContentDataH")(1).innerText
                    ThisWorkbook.Worksheets("Sheet1").Cells(u, 6) = .getElementsByClassName("formContentData")(3).innerText
                    ThisWorkbook.Worksheets("Sheet1").Cells(u, 7) = .getElementsByClassName("formContentData")(4).innerText
                    ThisWorkbook.Worksheets("Sheet1").Cells(u, 8) = .getElementsByClassName("formContentData")(5).innerText
                    ThisWorkbook.Worksheets("Sheet1").Cells(u, 9) = .getElementsByClassName("formContentData")(9).innerText
                End With
                On Error GoTo 0
            End If
        Next u
    End With
End Sub

【讨论】:

  • 谢谢QHarr,:)
  • 很高兴它有帮助:-)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-04-09
相关资源
最近更新 更多