Web抓取:如何使用Instr函数匹配字符串

时间:2019-08-25 12:48:28

标签: html vba internet-explorer web-scraping

我正在欧洲央行网站上进行网上抓取以获取年度报告,以便进行更多实践。找到页面的所有pdf href后,我得到如下所示的字符串负载:

https://www.ecb.europa.eu/pub/pdf/annrep/ar2016en.pdf?cb49eb74de9ddf1f55ebe03fb610d05b
https://www.ecb.europa.eu/pub/pdf/annrep/ar2015en.pdf?2e7998c5daf6a2a7e4bfccb41e81b504
https://www.ecb.europa.eu/pub/pdf/annrep/ar2014en.pdf?20def41d1b09b84d5889c707f92c9e4a
https://www.ecb.europa.eu/pub/pdf/annrep/ar2013en.pdf?fad3a17bf210c3c411c6e3c3121eb8a1
https://www.ecb.europa.eu/pub/pdf/annrep/ar2012en.pdf?40f7b4588f9adb8cf61ce44014c1b088

以此类推。

现在,我想执行一个操作,如果用户提交的字符串包含在其中的href中,则单击该href。 (例如,我插入2015,然后单击第二个href)

我尝试使用Instr,但只有在插入完整的href时,它才有效。

我的代码是这样的:

Sub prova()

Dim Ie As New SHDocVw.InternetExplorer
Dim Iedoc As MSHTML.HTMLDocument
Dim element As Object
Dim elements As MSHTML.IHTMLElementCollection
Dim parameter As String

parameter = "2015" 'i will insert application.inputbox


With Ie:
    .navigate "https://www.ecb.europa.eu/pub/annual/html/index.en.html"
    .Visible = True
End With

While Ie.readyState <> READYSTATE_COMPLETE Or Ie.Busy: DoEvents: Wend

Set Iedoc = Ie.document

Set elements = Iedoc.getElementsByClassName("pdf")

For Each element In elements:
    If InStr(1, parameter, element) Then
    element.Click
    End If
    Debug.Print element
    Next element

1 个答案:

答案 0 :(得分:2)

Instr需要一个字符串而不是对象作为要搜索的参数。

Syntax

  

InStr([开始],字符串1,字符串2,[比较])

顺序也是:

  

string1必需。正在搜索字符串表达式。

     

string2必需。寻求字符串表达式

根据要搜索的字符串及其位置,可以选择InStrRev从源字符串的末尾搜索以更快地进行匹配。请注意,参数为:

  

InstrRev(stringcheck,stringmatch,[开始,[比较]])

从技术上讲,我认为这是签名中的一个参数,但值传递时是一个参数。虽然有人可以纠正我的错误。


您应该使用href

InStr(1, href, param) >0

一按即可使用outerHTML,但搜索空间较大,因此效率较低。

使用css attribute = value选择器(包含*,以^开头或以$运算符结尾)简单地使用DOM解析器来过滤结果,效率更高:

contains运算符:

Iedoc.querySelector("[href*='" &  parameter & "'").click

href属性中测试更长的子字符串会更安全,例如:

param = 2015 
Iedoc.querySelector(".doc-title [href*='/pub/annual/html/ar" & param & "']").click

然后您将摆脱整个循环。


旁注:

在您当前的循环中,您可能还希望找到匹配后的Exit For

如果找到匹配项,

Debug.Print element将仅打印[Object]

您可能要访问元素本身的属性,例如.innerText。但是,只要您单击它,如果现在不再将元素附加到DOM,则可能会冒泡一个陈旧的元素异常(或其他错误)。