使用VBA提取一系列URL

时间:2018-09-29 13:51:11

标签: html excel vba web-scraping

我只是尝试遍历url链接列表,但它始终显示运行时错误“ 91”,对象变量或未设置块变量。

我要提取的数据来自iframe。它确实显示了一些值,但是卡在进程中间,并显示错误。

下面是我要从其中提取值的示例网址链接:http://www.bursamalaysia.com/market/listed-companies/company-announcements/5927201

Public Sub GetInfo()
    Dim IE As New InternetExplorer 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) = .getElementById("main").innerText
            ThisWorkbook.Worksheets("Sheet1").Cells(u, 4) = .getElementsByClassName("company_name")(0).innerText
            ThisWorkbook.Worksheets("Sheet1").Cells(u, 5) = .getElementsByClassName("formContentData")(0).innerText
            ThisWorkbook.Worksheets("Sheet1").Cells(u, 6) = .getElementsByClassName("formContentData")(5).innerText
            ThisWorkbook.Worksheets("Sheet1").Cells(u, 7) = .getElementsByClassName("formContentData")(7).innerText
            ThisWorkbook.Worksheets("Sheet1").Cells(u, 8) = .getElementsByClassName("formContentData")(8).innerText
            ThisWorkbook.Worksheets("Sheet1").Cells(u, 9) = .getElementsByClassName("formContentData")(9).innerText
            ThisWorkbook.Worksheets("Sheet1").Cells(u, 10) = .getElementsByClassName("formContentData")(10).innerText
            ThisWorkbook.Worksheets("Sheet1").Cells(u, 11) = .getElementsByClassName("formContentData")(11).innerText
       End With

    Next u
    End With
End Sub

1 个答案:

答案 0 :(得分:1)

tl; dr

您的错误是由于以下事实造成的:给定类名的元素数量不同,具体取决于每页的结果。因此,您不能使用固定索引。对于该页面,您通过iframe指示了该类的最后一个索引是9,即ThisWorkbook.Worksheets("Sheet1").cells(u, 9) = .getElementsByClassName("formContentData")(9).innerText。 10和11无效。下面,我展示一种确定结果数量并从每个结果行中提取信息的方法。

一般原则:

好吧...因此,以下内容基于针对大多数信息的Details of Changes表为目标的原理。

示例摘录:

更具体地说,我将针对No, Date of Change, #Securities, Type of Transaction and Nature of Interest重复信息的行作为目标。这些值存储在一个数组数组中(每行信息一个数组)。然后将结果数组存储在一个集合中,以便稍后写出到工作表中。我在目标行(父级td中的tr标签元素)中循环每个表格单元,以填充数组。

我在页面上方的表格中添加了Name,而且由于结果可能会导致一行以上的结果(具体取决于网页),并且因为我正在将结果写入新的{{ 1}}工作表中,我在每个结果之前添加Results,以指示信息来源。


待办事项:

  1. 重构代码使其更具模块化
  2. 可能会添加一些错误处理

CSS选择器:


①我从URL表中选择Name元素,称为title

名称元素示例:

enter image description here

检查此元素的HTML显示其具有Particulars of substantial Securities Holder类,并且它是页面上具有该值的第一类。

目标名称的示例HTML:

enter image description here

这意味着我可以使用class selectorformContentLabel来定位元素。因为它是一个元素,所以我想使用.formContentLabel方法来应用CSS选择器。


②我用querySelector的选择器组合定位Details of Changes表中感兴趣的行。这是descendant selector组合,将带有.ven_table tr标签的选择元素与父类为tr的标签组合在一起。由于这些是多个元素,因此我使用ven_table方法来应用CSS选择器组合。

目标行的示例:

enter image description here


CSS选择器返回的示例结果(示例):

enter image description here

我感兴趣的行从1开始,例如每隔+ 4行重复一次。第5、9等行 因此,我在代码中使用了一些数学运算以仅返回感兴趣的行:

querySelectorAll

VBA:

Set currentRow = data.item(i * 4 + 1)

使用2个提供的测试URL的示例结果:

enter image description here


工作表1中的示例URL:

  1. http://www.bursamalaysia.com/market/listed-companies/company-announcements/5928057
  2. http://www.bursamalaysia.com/market/listed-companies/company-announcements/5927201