【问题标题】:Scraping Web data from a database platform (VBA - HTML)从数据库平台抓取 Web 数据 (VBA - HTML)
【发布时间】:2020-01-23 18:18:30
【问题描述】:

我不擅长开发,但我需要为一个小型自动化项目完成这项任务。 情况是我必须登录到数据库并打印出一些数据到excel,这是为了检查 数据是否被删除。

我想从代码中得到什么?

通过单击 Excel 中的宏按钮:

  • 登录网站 [x]
  • 搜索给定的数字 [x]
  • 在 excel 中打印回元素 [] 的状态
  • 从第 2 步开始重复,直到 A 列中出现数字(哪个循环?)[]

https://imgur.com/u4IhpW7

正如您在 Excel 屏幕截图中看到的那样,单元格 A9 是数字列表的开始位置。 在单元格 B9 下,我希望根据左侧的每个数字打印出我的数据。

所以我已经成功登录并搜索了第一个号码。

这里是整个代码:

Sub Login()

    Dim ie As New SHDocVw.InternetExplorer
    Dim HTMLDoc As MSHTML.HTMLDocument
    Dim HTMLInput As MSHTML.IHTMLElement

    ie.Visible = True

    ie.Navigate Sheet1.Range("B2").Text

    Do While ie.ReadyState <> READYSTATE_COMPLETE
    DoEvents
    Loop

    Set HTMLDoc = ie.Document

'Setting Username to a specific value
    Set HTMLInput = HTMLDoc.getElementById("ctl00_WebPartManager1_gwpLogin1_Login1_UserName")

    HTMLInput.Value = Sheet1.Range("B3")

'Setting Password to a specific value
    Set HTMLInput = HTMLDoc.getElementById("ctl00_WebPartManager1_gwpLogin1_Login1_Password")

    HTMLInput.Value = Sheet1.Range("B4")
'Click to login
    Set HTMLInput = HTMLDoc.getElementById("ctl00_WebPartManager1_gwpLogin1_Login1_LoginButton")

    HTMLInput.Click

    MsgBox "Login Succesfull" & vbCrLf & "Press Ok to check LIAB"

    While ie.Busy
        DoEvents
    Wend

    Set HTMLInput = HTMLDoc.getElementById("ctl00_SearchSection_ObjectSearch_txtEMail")
    HTMLInput.Value = Null

    Set HTMLInput = HTMLDoc.getElementById("ctl00_SearchSection_ObjectSearch_txtCustomerID")
    HTMLInput.Value = Sheet1.Range("A10")

    Set HTMLInput = HTMLDoc.getElementById("ctl00_SearchSection_ObjectSearch_SearchButton")
    HTMLInput.Click

    While ie.Busy
        DoEvents
    Wend
'On Error Resume Next
End Sub

第二部分可能不正确,但这就是我设法搜索给定数字的方式。 我必须弄清楚如何循环,直到从 A9 开始的 A 列中出现数字。

这就是网站的样子

https://imgur.com/4GJQ4oF

所以我需要从 B9 开始在 B 列中打印的是“状态”的内部文本。 还有一个条件要满足,如果状态的内部文本是“已删除”但“名称”的内部文本不为空,则在 B 列中打印错误。

所以有问题的表有没有 ID 的标签,所以我不知道如何操作它们。 另一件要提的是,如果字段为空,则 innerText 显示为:

 

在此先感谢您提供的任何帮助以及阅读所有这些内容的关注。

您好,

阿莱西奥

更新更改:

'Declared the new variable
    Dim iC as Integer
'........All the login part here........'
    MsgBox "Login Succesfull" & vbCrLf & "Press Ok to check LIAB"

    While ie.Busy
        DoEvents
    Wend
For iC = 10 To 29
'Now able to loop through a specific amount of cells, still not dynamic, still no idea how to pull the data from the td tags

    Set HTMLInput = HTMLDoc.getElementById("ctl00_SearchSection_ObjectSearch_txtCustomerID")
    HTMLInput.Value = Sheet1.Range("A" & iC)

    Set HTMLInput = HTMLDoc.getElementById("ctl00_SearchSection_ObjectSearch_SearchButton")
    HTMLInput.Click

    While ie.Busy
        DoEvents
    Wend
   Next
'On Error Resume Next
End Sub'

【问题讨论】:

  • 嗨,欢迎来到 SO。我不明白你的问题。运行代码时是否出现错误?如果是这样,它是什么以及哪一行引发了错误?如果没有,您是否只是在向代码添加循环时寻求帮助,以便您可以在Column B 中完成所有相关单元格?顺便说一句,对于不擅长开发的人来说,该代码非常好!
  • 嗨,扎克,很抱歉不清楚。目前没有错误,是的,我正在寻求帮助,因为我被困在这一点上。感谢您的反馈,上周我花了很多时间寻找这些事情是如何完成的,但每个案例都不同。问题是我自己也缺少语法和代码结构的基础知识,而且我没有太多时间深入研究基础知识。
  • 如果它只是一个你需要的循环,那么在你登录之后(以及在你登录后的第一个Set HTMLInput =... 语句之前)添加一个for循环:For iC = 10 To 16。然后您可以将HTMLInput.Value = Sheet1.Range("A10") 更改为HTMLInput.Value = Sheet1.Range("A" &amp; iC)。这将循环通过你的细胞。还有其他需要考虑的事情: 1. 找到A 列中的最后一个单元格,使您的FOR 循环动态化。 2. 如何在Column B 中捕获结果。但是 IMO,小步骤将帮助您了解正在发生的事情
  • 我明白了,我添加了这个循环并且工作正常,正如你所说的,我仍然需要弄清楚如何使其动态化以及如何记录数据。谢谢扎克!
  • 如果我有时间,我会发布代码以使其如此

标签: html excel vba web-scraping


【解决方案1】:

由于您只需要循环方面的帮助,我只是在循环中和循环周围发布代码。我还没有测试过这段代码,但希望它能工作

Dim iC As Long
Dim iLastRow As Long: iLastRow = Sheet1.Range("A" & Sheet1.Rows.Count).End(xlUp).Row
Dim HTMLInput As MSHTML.IHTMLElement
Dim oSearchButton As MSHTML.IHTMLElement: Set oSearchButton = HTMLDoc.getElementById("ctl00_SearchSection_ObjectSearch_SearchButton")

' Loop through all avaiable customer IDs
For iC = 10 To iLastRow

    ' Set Customer ID
    Set HTMLInput = HTMLDoc.getElementById("ctl00_SearchSection_ObjectSearch_txtCustomerID")
    HTMLInput.Value = Sheet1.Range("A" & iC)

    ' Press Search button
    oSearchButton.Click

    ' Wait for browser to complete task
    While ie.Busy
        DoEvents
    Wend

    ' Capture Status in colmn B
    Set HTMLInput = HTMLDoc.getElementById("ctl00_SearchSection_ObjectSearch_txtCustomerID")    ' Change element ID to point to status element
    Sheet1.Range("B" & iC) = HTMLInput.Value

Next

提示:如果元素 ID 不变,您可以在 For 循环之外声明您的元素(客户 ID 元素和状态元素),然后在循环中使用它们,就像我用oSearchButton 元素做了

【讨论】:

  • 嗨,扎克,感谢您发布此消息。我有几个问题:我可以在我之前声明的顶部添加Dim iC As Long Dim iLastRow As Long: iLastRow = Sheet1.Range("A" &amp; Sheet1.Rows.Count).End(xlUp).RowDim oSearchButton As MSHTML.IHTMLElement 的声明吗?您是否声明oSearchButton 只是为了避免重复HTML ID,并在需要时写下这个oSearchButton.Click?关于捕获 B 列中的状态,您建议使用 ID 方法,但正如您在第二个屏幕中看到的 /td 标签没有 ID!如何解决这个问题?提前致谢
  • 是的,您可以在顶部声明它们。唯一的区别是这个位:Set oSearchButton = HTMLDoc.getElementById("ctl00_SearchSection_ObjectSearch_SearchButton") 必须在页面加载之后(所以就在For 循环之前)。这正是我在循环之外声明它的原因:以避免重复。更棘手的一点是识别和捕获状态。您将必须捕获 table(我认为它的 ID = grid),然后根据行捕获状态。网上有很多关于如何做到这一点的例子。如果不告诉我
  • 嗨 Zac,我搜索并找到了一些东西,但我仍在努力寻找提取状态的正确方法。 For iC = 10 To iLastRow Set HTMLInput = HTMLDoc.getElementById("ctl00_SearchSection_ObjectSearch_txtCustomerID") HTMLInput.Value = Sheet1.Range("A" &amp; iC) oSearchButton.Click ...Wait for IE to load stuff... Wend Set HTMLInput = HTMLDoc.getElementById("ctl00_ListSection_UpdatePanel1") Set HTMLInput = HTMLDoc.getElementsByClassName("grid") Set HTMLInput = HTMLDoc.getElementsByClassName("gridRow").Item(3) Debug.Print HTMLInput.innerText
  • 我收到错误 13 表示该类型不受支持
  • Have a look at this。不是最好的编码实践,也许我们可以有更好的方法,但它会让你知道你哪里出错了
猜你喜欢
  • 1970-01-01
  • 2016-10-04
  • 2023-03-13
  • 2021-08-08
  • 1970-01-01
  • 2021-01-01
  • 2015-04-22
  • 2015-01-19
相关资源
最近更新 更多