【问题标题】:Excel VBA: Extract Image Src attribute from HTML as stringExcel VBA:从 HTML 中提取图像 Src 属性作为字符串
【发布时间】:2020-07-08 18:19:32
【问题描述】:

我正在尝试抓取我的雇主网站以从他们的博客文章中大量提取图像。我已经开始使用 VBA 在 Excel 中创建一个抓取工具。

(我们无权访问 SQL 数据库)

我已经设置了一个工作表,其中包含 A 列中的帖子标识符列表和 B 列中帖子的 URL。

到目前为止,我的 VBA 脚本通过 B 列中的 URL 列表运行,使用 getElementById 从页面上的标签中提取 HTML,并将结果输出作为字符串粘贴到 C 列中。

我现在正试图弄清楚如何从结果输出中的每个图像中提取 src 属性并将其粘贴到相关列中。我一辈子都想不出一个简单的解决方案。我对 RegEx 不是很熟悉,并且正在努力使用 Excel 的内置字符串函数。

最终的游戏是让宏通过每个图像 URL 运行并将图像以“{Event No.}-{Image Number}”.jpg 之类的文件名格式保存到磁盘

任何帮助将不胜感激。

Worksheet setup

Sub Get_Image_SRC()

Dim sht As Worksheet
Dim LastRow As Long
Dim i As Integer
Dim url As String
Dim IE As Object
Dim objElement As Object
Dim objCollection As Object
Dim Elements As IHTMLElementCollection
Dim Element As IHTMLElement


Set sht = ThisWorkbook.Worksheets("Sheet1")
'Ctrl + Shift + End
LastRow = sht.Cells(sht.Rows.Count, "A").End(xlUp).Row
Set IE = CreateObject("InternetExplorer.Application")
IE.Visible = True
For i = 2 To LastRow
    url = Cells(i, "C").Value
    MsgBox (url)
    IE.navigate url
    Application.StatusBar = url & " is loading..."
    Do While IE.readyState = 4: DoEvents: Loop
    Do Until IE.readyState = 4: DoEvents: Loop
    Application.StatusBar = url & " Loaded"
    If Cells(i, "B").Value = "WEBNEWS" Then
        Cells(i, "D").Value = IE.document.getElementById("NewsDetail").outerHTML
       Else
        Cells(i, "D").Value = IE.document.getElementById("ReviewContainer").outerHTML
    End If



Next i

Set IE = Nothing
Set objElement = Nothing
Set objCollection = Nothing

End Sub

生成的 HTML 示例:

<div id=""NewsDetail""><div class=""NewsDetailTitle"">Video: Race Face Behind the Scenes Tour</div><div class=""NewsDetailImage""><img alt=""HeadlinesThumbnail.jpg"" src=""/ImageHandler/6190/515/1000/0/""></div>    <div class=""NewsDetailBody"">Pinkbike posted this video a while ago, if you missed it, its' definitely worth a watch. 

Ken from Camp of Champions took a look at their New Westminster factory last year which gives a look at the production, people and culture of Race Face. The staff at Race Face are truly their greatest asset they had, best wishes to everyone!

<p><center><object width=""500"" height=""281""><param name=""allowFullScreen"" value=""true""><param name=""AllowScriptAccess"" value=""always""><param name=""movie"" value=""http://www.pinkbike.com/v/188244""><embed width=""500"" height=""281"" src=""http://www.pinkbike.com/v/188244"" type=""application/x-shockwave-flash"" allowscriptaccess=""always"" allowfullscreen=""true""></object></center><p></p>


</div><div class=""NewsDate"">Published Friday, 25 November 2011</div></div>"

My current references

【问题讨论】:

    标签: excel vba web-scraping


    【解决方案1】:

    当您可以使用 Wget 轻松完成此操作时,使用 VBA 似乎非常复杂:How do I use Wget to download all Images into a single Folder

    【讨论】:

    • 我只需要每个页面特定部分的图像,并要求图像以这样的方式标记,以便它们可以匹配到特定页面和文本中的位置。我也在 Windows 上,无法访问 *nix 框。
    【解决方案2】:

    对于正则表达式方法,您应该查看以下两个链接:

    这基本上归结为:

    • img获取src属性值的正则表达式是src\s*=\s*"(.+?)"
    • 使用 VBScript.RegExp 库在 VBA 中使用正则表达式

    我使用了后期绑定,但您可以根据需要包含参考。

    然后 VBA 是这样的:

    选项显式

    子测试()

    Dim strHtml As String
    
    ' sample html, note single img tag
    strHtml = ""
    strHtml = strHtml & "<div id=""foo"">"
    strHtml = strHtml & "<bar class=""baz"">"
    strHtml = strHtml & "<img alt=""fred"" src=""\\server\path\picture1.png"" />"
    strHtml = strHtml & "</bar>"
    strHtml = strHtml & "<bar class=""baz"">"
    strHtml = strHtml & "<img alt=""ned"" src=""\\server\path\picture2.png"" />"
    strHtml = strHtml & "</bar>"
    strHtml = strHtml & "<bar class=""baz"">"
    strHtml = strHtml & "<img alt=""teddy"" src=""\\server\path\picture3.png"" />"
    strHtml = strHtml & "</bar>"
    strHtml = strHtml & "</div>"
    
    Dim strSrc As String
    Dim objRegex As Object
    Dim objMatches As Object
    Dim lngMatchCount As Long, lngCounter As Long
    
    ' create regex
    Set objRegex = CreateObject("VBScript.RegExp")
    
    ' set pattern and execute
    With objRegex
        .IgnoreCase = True
        .Pattern = "src\s*=\s*""(.+?)"""
        .Global = True
    
        If .Test(strHtml) Then
            Set objMatches = .Execute(strHtml)
            lngMatchCount = objMatches.Count
            For lngCounter = 0 To lngMatchCount - 1
                strSrc = objMatches(lngCounter).SubMatches(0)
                ' youve successfully captured the img src value
                Debug.Print strSrc
            Next
        Else
            strSrc = "Not found"
        End If
    End With
    

    结束子

    请注意,我获取SubMatches 集合的第一项是为了获取src 属性的值。这段代码中objMatches(0)objMatches(0).SubMatches(0)的区别是:

    src="\\server\path\picture.png"
    

    对比:

    \\server\path\picture.png
    

    您可能希望将其包装为一个函数,并在您的代码的 If..End If 块中计算出 IE.document.getElementById("NewsDetail").outerHTML 的值时调用它。

    【讨论】:

    • 谢谢,罗宾。这适用于具有单个图像的页面。请问您将如何修改它以获取多个图像?
    • @user2866975 - 查看我的编辑 - 基本上需要将 Global 标志设置为 true,然后遍历所有匹配项。
    猜你喜欢
    • 2013-02-03
    • 1970-01-01
    • 1970-01-01
    • 2016-05-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多