Html 使用siriusxm.com上的XHR进行Web刮取

Html 使用siriusxm.com上的XHR进行Web刮取,html,vba,excel,web-scraping,xmlhttprequest,Html,Vba,Excel,Web Scraping,Xmlhttprequest,我需要从中提取当前正在播放的艺术家和歌曲。我可以使用Internet Explorer导航到网站,但这需要很长时间,因此我尝试使用WINHTTP.WinHTTPRequest.5.1和MSXML2.serverXMLHTTP,但两者都没有提取我要查找的特定数据。我想我很接近,但我错过了一些东西 以下是HTML代码段: 吸烟/酷玩 类似这样的东西 ... ... 这是我目前的代码: Sub-GetData() 以艺术家为对象 Dim getSong作为对象 设置xmHtml=newhtmldo

我需要从中提取当前正在播放的艺术家和歌曲。我可以使用Internet Explorer导航到网站,但这需要很长时间,因此我尝试使用
WINHTTP.WinHTTPRequest.5.1
MSXML2.serverXMLHTTP
,但两者都没有提取我要查找的特定数据。我想我很接近,但我错过了一些东西

以下是HTML代码段:


吸烟/酷玩

类似这样的东西

... ...
这是我目前的代码:

Sub-GetData()
以艺术家为对象
Dim getSong作为对象
设置xmHtml=newhtmldocument
使用CreateObject(“WINHTTP.WinHTTPRequest.5.1”)
.打开“获取”http://www.siriusxm.com/siriusxmhits1”“错
.发送
xmHtml.body.innerHTML=.responseText
以
设置getArtist=xmHtml.getElementById(“onair pdt”).getElementsByTagName(“p”)(0)
MsgBox(getArtist.innerText)
设置getSong=xmHtml.getElementById(“onair pdt”).getElementsByTagName(“p”)(1)
MsgBox(getSong.innerText)
端接头
如果我激活Internet Explorer,它将使用以下代码工作,但这对于我需要执行的操作来说太长了:

Sub-GetData()
Dim DivID作为HTMLObjectElement
Dim GetArtister作为变体
Dim getSong作为变体
URL=”http://www.siriusxm.com/siriusxmhits1"
带着IExplore
.浏览网址
.Visible=False
执行While.readyState 4:DoEvents:Loop
设置文档=.doc
Set DivID=doc.getElementById(“onair pdt”)
getArtist=DivID.GetElementsByCassName(“onair pdt艺术家”)(0.innerText
getSong=doc.GetElementsByCassName(“onair pdt song”)(0)
以
端接头
该网站提供了一种API。我通过Chrome中的链接浏览了一个页面,然后打开了开发者工具窗口(F12),网络选项卡,并检查了列表中的XHR。当前歌曲信息可以通过电子邮件检索。G在以下步骤中:

  • 通过URL生成XHR以检索当前时间戳

  • 使用URL最后一个数字中的当前时间戳生成XHR

  • 解析收到的JSON响应

  • 获取歌曲名称为
    JSON.channelMetadataResponse.metaData.currentEvent.song.name
    ,艺术家名称为
    JSON.channelMetadataResponse.metaData.currentEvent.artists.name
    ,等等

下面是显示JSON响应结构的示例,我使用在线工具:

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

选项显式
子测试_siriusxm_com()
像线一样变暗
日期
作为字符串的Dim sUrl
Dim vJSON作为变量
将状态设置为字符串
朦胧的萨提斯式弦乐
作为字符串的Dim sComposer
朦胧的沙尔布
作为一根弦
'检索时间戳
使用CreateObject(“MSXML2.XMLHTTP”)
.打开“获取”http://www.siriusxm.com/sxm_date_feed.tzi”“错
.发送
s=.responseText
以
'将时间戳解析为日期类型
d=CDate(日期序列(Mid(s,5,4),Mid(s,3,2),Mid(s,1,2))+时间序列(Mid(s,9,2),Mid(s,11,2),Mid(s,13,2)))
'添加4小时以从EDT时区获取UTC
d=日期添加(“h”,4,d)
'将URL与时间戳组合
苏尔=”http://www.siriusxm.com/metadata/pdt/en-us/json/channels/siriushits1/timestamp/" & _
LZ(月(d)、2)和“-”和_
LZ(日(d),2)和“-”和_
LZ(小时(d),2)和“&”_
LZ(d分钟,2分钟)和“&”_
"00"
'检索channelMetadataResponse JSON数据
使用CreateObject(“MSXML2.XMLHTTP”)
.打开“GET”,sUrl,False
.发送
s=.responseText
以
'解析JSON响应
解析s,vJSON,sState
'检查是否有效
如果指定“对象”,则
MsgBox“无效的JSON响应”
出口接头
如果结束
“检查是否可用
如果vJSON(“channelMetadataResponse”)(“消息”)(“代码”)“100”,则
MsgBox“不可用内容”
出口接头
如果结束
'获取必要的属性
设置vJSON=vJSON(“channelMetadataResponse”)(“元数据”)(“currentEvent”)
sArtists=vJSON(“艺术家”)(“姓名”)
sComposer=vJSON(“歌曲”)(“作曲家”)
sAlbum=vJSON(“歌曲”)(“专辑”)(“名字”)
SSON=vJSON(“歌曲”)(“名称”)
"产出结果",
MsgBox“直播”&vbCrLf&_
“艺术家:”&sArtists&vbCrLf&_
“作曲者:”&sComposer&vbCrLf&_
专辑:&sAlbum&vbCrLf&_
宋:&宋
端接头
函数LZ(n为字符串,q为长)为字符串“添加前导零”
LZ=右(字符串(q,“0”)&n,q)
端函数

顺便说一句,采用了类似的方法。

谢谢。我添加了json.bas和所有适当的引用。我对JSON.Parse s,vJSON,sState行有一个问题。当我转到JSON.bas文件中的Parse函数时,我得到的错误是“编译错误:参数数目错误或属性分配无效”,看起来它只查找一个字符串,在本例中是变量s。如果我改为“JSON.Parse s”,我可以让它运行,但sState从未被赋值,在接下来的几行中它退出。如果跳过该语句,则在尝试设置vJSON时会出现“类型不匹配”错误。谢谢。@mh2017我发布的JSON.bas的链接是错误的,我编辑了答案,请检查链接。是的。谢谢你的意见。实际上你教了我很多。