【问题标题】:Web scrape using XHR from siriusxm.com使用来自 siriusxm.com 的 XHR 进行网络抓取
【发布时间】:2017-09-04 19:36:32
【问题描述】:

我需要从http://www.siriusxm.com/siriusxmhits1 中提取当前正在播放的艺术家和歌曲。我可以使用 Internet Explorer 导航到该网站,但这需要很长时间,所以我尝试使用 WINHTTP.WinHTTPRequest.5.1MSXML2.serverXMLHTTP 但都没有提取我正在寻找的特定数据。我想我已经很接近了,但我错过了一些东西。

下面是 HTML sn-p:

<div id="on-the-air-content" style="display: block;">
    <div class="module-content theme-color-content-bg clearfix">
        <div id="onair-pdt" style="display: block;">
            <img alt="" src="//www.siriusxm.com/albumart/Live/2000/chainsmokers_58C328AC_t.jpg">
            <p class="onair-pdt-artist">Chainsmokers/Coldplay</p>
            <p class="onair-pdt-song">Something Just Like This</p>
        </div>
        ...
    </div>
    ...
</div>

这是我当前的代码:

Sub GetData()

    Dim getArtist As Object
    Dim getSong As Object

    Set xmHtml = New HTMLDocument
    With CreateObject("WINHTTP.WinHTTPRequest.5.1")
        .Open "GET", "http://www.siriusxm.com/siriusxmhits1", False
        .send
        xmHtml.body.innerHTML = .responseText
    End With
    Set getArtist = xmHtml.getElementById("onair-pdt").getElementsByTagName("p")(0)
    MsgBox (getArtist.innerText)
    Set getSong = xmHtml.getElementById("onair-pdt").getElementsByTagName("p")(1)
    MsgBox (getSong.innerText)

End Sub

如果我激活 Internet Explorer,它将使用以下代码工作,但这对于我需要做的事情来说太长了:

Sub GetData()

    Dim DivID As HTMLObjectElement
    Dim getArtist As Variant
    Dim getSong As Variant

    URL = "http://www.siriusxm.com/siriusxmhits1"
    With IExplore
        .Navigate URL
        .Visible = False
        Do While .readyState <> 4: DoEvents: Loop
        Set doc = .document
        Set DivID = doc.getElementById("onair-pdt")
        getArtist = DivID.getElementsByClassName("onair-pdt-artist")(0).innerText
        getSong = doc.getElementsByClassName("onair-pdt-song")(0).innerText
    End With

End Sub

【问题讨论】:

    标签: html vba excel web-scraping xmlhttprequest


    【解决方案1】:

    http://www.siriusxm.com 网站有一种可用的 API。我在 Chrome 中通过链接 http://www.siriusxm.com/hits1 浏览了一个页面,然后打开了开发者工具窗口 (F12)、网络选项卡,并检查了列表中的 XHR。可以检索当前歌曲信息 e。 G。在以下步骤中:

    下面是显示JSON响应结构的示例,我使用在线工具http://jsonviewer.stack.hu

    您可以使用下面的 VBA 代码来检索上述信息。 JSON.bas 模块导入VBA 项目进行JSON 处理。

    Option Explicit
    
    Sub Test_siriusxm_com()
    
        Dim s As String
        Dim d As Date
        Dim sUrl As String
        Dim vJSON As Variant
        Dim sState As String
        Dim sArtists As String
        Dim sComposer As String
        Dim sAlbum As String
        Dim sSong As String
    
        ' Retrieve timestamp
        With CreateObject("MSXML2.XMLHTTP")
            .Open "GET", "http://www.siriusxm.com/sxm_date_feed.tzi", False
            .send
            s = .responseText
        End With
        ' Parse timestamp to Date type
        d = CDate(DateSerial(Mid(s, 5, 4), Mid(s, 3, 2), Mid(s, 1, 2)) + TimeSerial(Mid(s, 9, 2), Mid(s, 11, 2), Mid(s, 13, 2)))
        ' Add 4 hours to get UTC from EDT timezone
        d = DateAdd("h", 4, d)
        ' Combine URL with timestamp
        sUrl = "http://www.siriusxm.com/metadata/pdt/en-us/json/channels/siriushits1/timestamp/" & _
                LZ(Month(d), 2) & "-" & _
                LZ(Day(d), 2) & "-" & _
                LZ(Hour(d), 2) & ":" & _
                LZ(Minute(d), 2) & ":" & _
                "00"
        ' Retrieve channelMetadataResponse JSON data
        With CreateObject("MSXML2.XMLHTTP")
            .Open "GET", sUrl, False
            .send
            s = .responseText
        End With
        ' Parse JSON response
        JSON.Parse s, vJSON, sState
        ' Check if valid
        If sState <> "Object" Then
            MsgBox "Invalid JSON response"
            Exit Sub
        End If
        ' Check if available
        If vJSON("channelMetadataResponse")("messages")("code") <> "100" Then
            MsgBox "Unavailable content"
            Exit Sub
        End If
        ' Get necessary properties
        Set vJSON = vJSON("channelMetadataResponse")("metaData")("currentEvent")
        sArtists = vJSON("artists")("name")
        sComposer = vJSON("song")("composer")
        sAlbum = vJSON("song")("album")("name")
        sSong = vJSON("song")("name")
        ' Output results
        MsgBox "On the Air" & vbCrLf & _
            "Artists: " & sArtists & vbCrLf & _
            "Composer: " & sComposer & vbCrLf & _
            "Album: " & sAlbum & vbCrLf & _
            "Song: " & sSong
    
    End Sub
    
    Function LZ(n As String, q As Long) As String ' Add leading zeroes
        LZ = Right(String(q, "0") & n, q)
    End Function
    

    顺便说一句,类似的方法适用于in other answers

    【讨论】:

    • 感谢 omegastripes。我添加了 json.bas 和所有适当的引用。我的 JSON.Parse s, vJSON, sState 行有问题 我得到的错误是“编译错误:参数数量错误或属性分配无效” 当我转到 json.bas 文件中的 Parse 函数时,它看起来就像它只在寻找一个字符串,在这种情况下是变量 s。如果我更改为“JSON.Parse s”,我可以让它运行,但 sState 永远不会被赋值,并且在接下来的几行中它会退出。如果我跳过该语句,在尝试设置 vJSON 时会出现“类型不匹配”错误。谢谢。
    • @mh2017 我发布的 JSON.bas 的链接错误,我编辑了答案,请检查链接。
    • 是的,做到了。谢谢您的意见。实际上,你教会了我很多东西。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-06-23
    • 2021-06-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多