【问题标题】:Extract the details from a Table using VBA gets object variable or with block variable not set使用 VBA 从表中提取详细信息获取对象变量或未设置块变量
【发布时间】:2020-12-17 06:55:03
【问题描述】:

我的脚本运行了几行,然后我获取对象变量或块变量未设置错误。

我正在使用以下脚本从 NSEIndia 网站中提取 5、6、7 值。

我从同一个 Excel 中获取股票的价值,并使用来自 nseindia 网站的值更新同一个 Excel。

Sub Stock_Basic_Update_NSE()
    Dim ie As InternetExplorer
    Dim webpage As HTMLDocument
    
    Dim ws As Worksheet
    
        
    For Item = 23 To 1505
    Set ws = ThisWorkbook.Worksheets("NSE Stocks Details")
       sSearch = ws.Range("A" & Item).Value
        'sSearch = Filestk.Worksheets("Sheet1").Range("E1").Value
        Set ie = New InternetExplorer
        'ie.Visible = True
        ie.navigate ("https://www.nseindia.com/get-quotes/equity?symbol=" & sSearch)
        Do While ie.readyState = 4: DoEvents: Loop
        Do Until ie.readyState = 4: DoEvents: Loop
        
        While ie.Busy
            DoEvents
        Wend
        Set webpage = ie.document
        ws.Cells(Item, 3).Value = webpage.getElementsByClassName("eq-series table-fullwidth w-100")(0).getElementsByTagName("td")(5).innerText
        ws.Cells(Item, 4).Value = webpage.getElementsByClassName("eq-series table-fullwidth w-100")(0).getElementsByTagName("td")(6).innerText
        ws.Cells(Item, 5).Value = webpage.getElementsByClassName("eq-series table-fullwidth w-100")(0).getElementsByTagName("td")(7).innerText
        ie.Quit
        Set ie = Nothing
    Next Item
End Sub

【问题讨论】:

  • A 列中的items 是什么?
  • 尝试将Set ws = ThisWorkbook.Worksheets("NSE Stocks Details")移出FOR循环
  • 尝试在Set webpage 之前使用延迟Application.Wait Now + TimeValue("00:00:05") 来消除该错误。您可以使用.document.getElementById("equityInfo").getElementsByTagName("td")(5).innerText.document.querySelector("#equityInfo td:nth-of-type(6)").innerText 来定位所需的元素,而不是使用您当前正在执行的复合类。更改索引应该会为您获取所需的内容。
  • @SIM 你的意思是错误基本上是在页面加载之前打印的值?
  • @SIM,我已将值增加到 10,因为它在运行 20 行后再次失败......我必须运行 2000 行。让我在它完全运行后告诉我。感谢您的支持和帮助

标签: html excel vba internet-explorer web-scraping


【解决方案1】:

您的代码中有一些错误,您没有等待完整的文档加载。试试下面的代码。我已经评论过了。所以你可以看到,我改变了什么以及为什么。我已经尝试了前 50 个符号。

Sub Stock_Basic_Update_NSE()
  'Declare always all variables
  Dim ie As Object 'I switched this from early to late binding (not required)
  Dim nodeTable As Object
  Dim ws As Worksheet
  Dim item As Long
  Dim sSearch As String
  
  'Use this outside the loop. You only need it once
  Set ws = ThisWorkbook.Worksheets("NSE Stocks Details")
  
  For item = 23 To 1505
    sSearch = ws.Range("A" & item).Value
    Set ie = CreateObject("internetexplorer.application")
    ie.Visible = False
    'Encode symbols that are restricted for using in URLs. Like &, : or ?
    ie.navigate ("https://www.nseindia.com/get-quotes/equity?symbol=" & WorksheetFunction.EncodeURL(sSearch))
    'It's not "While = 4" because 4 stands for "readystate = complete"
    'If you want to use "= 4" you must use "Until" instead of "While"
    'It doesn't matter what you use
    Do While ie.readyState <> 4: DoEvents: Loop
    'Manual break to load dynamic content after the IE reports the page load was complete
    'This was your main problem
    Application.Wait (Now + TimeSerial(0, 0, 2))
    
    'The needed html table has an ID. If possible use always that instead of class names
    'because an html ID is unique if the standard is kept
    'Also use a variable to save the elements
    'So you don't need to shorten the html document string in most cases because
    'it's only needed one time
    Set nodeTable = ie.document.getElementByID("equityInfo")
    ws.Cells(item, 3).Value = nodeTable.getElementsByTagName("td")(5).innerText
    ws.Cells(item, 4).Value = nodeTable.getElementsByTagName("td")(6).innerText
    ws.Cells(item, 5).Value = nodeTable.getElementsByTagName("td")(7).innerText
    
    'Clean up
    ie.Quit
    Set ie = Nothing
  Next item
End Sub

【讨论】:

  • 嗨,我将不可见标记为 true 并检查,IE 给出了权限被拒绝错误,因此页面现在没有加载。我很惊讶,它在 Chrome 浏览器中运行但抛出了这个错误。
  • 是否有任何 VBA 代码可以在 chrome 浏览器而不是 IE 中执行相同的操作?
  • @MSBalaji 使用除 IE 之外的其他浏览器的唯一方法是使用 Selenium。如果您收到“权限被拒绝”,您将被检测为机器人。 Chrome 也会发生同样的情况。您可以尝试在每 10 个或另一个工作量页面访问后设置几分钟的休息时间。或者手动设置加载动态内容为10秒或30秒。当然,makro 的运行时间会大大增加。但是,只要它比手动快,就可以了。无论如何,它不太容易出错。
  • 有道理...让我尝试确认一下。
  • @SIM,我能够成功运行脚本。我认为他们 NSE 网站阻止了我,几分钟后他们再次提供访问权限......所以多次运行脚本以获得解决方案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-05-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多