上一篇文章用VBA下载一部完整小说,VBA除了可以轻松下载一部《水浒传》小说,还有什么用途?VBA获取网页信息(即爬虫技术)其用处可多了。今天介绍各位小伙用来监控的自选股票的主力资金变动的情况,愿大伙在2022年股票市场长红!也是把上期一个网友评论的内容(有些数据藏得很深,怎么找真正的地址……)回应一下。
东富的主力资金流入图
有一个理论我们会经常听到,A股的票涨涨跌跌主要是因为有大资金在活动、在操作,一些股票不断上涨是因为有主力资金不断买入,反而不断下跌是因为主力资金不断流出。喜欢做短线的,我们实时观察这些主力资金就变得很有意义,很多网站都有主力资金的数据,但是要对多支股票进行观察,则需要一个个打开网页、APP或者电脑程序查看数据,这样耗时也不能多支股票同框对比。还有一些小伙正上班,打开股票软件给老板或同事看到,总觉得怪怪的,当然这不是鼓励一些小伙上班玩股票,纯属用项目和大家一起交流学习。
用VBA就可以很轻松解决上述两个问题。大伙先看看效果吧!
点击按钮更新数据:2022年12月21日数据
完整代码如下:
Sub maincapital()
Application.DisplayAlerts = False
'循环A列数据,解析出相应股票代码
For Each cl In Range("a2:a" & Range("a2").End(xlDown).Row)
stock_code = Right(cl, 6) '取右边6位字符
Dim strText, stcok_code As String
'拼接构造网址
URL = "https://push2.eastmoney.com/api/qt/ulist.np/get?cb=fltt=2&secids=1." + stock_code + "&fields=f62%2Cf184%2Cf66%2Cf69%2Cf72%2Cf75%2Cf78%2Cf81%2Cf84%2Cf87%2Cf64%2Cf65%2Cf70%2Cf71%2Cf76%2Cf77%2Cf82%2Cf83%2Cf164%2Cf166%2Cf168%2Cf170%2Cf172%2Cf252%2Cf253%2Cf254%2Cf255%2Cf256%2Cf124%2Cf6%2Cf278%2Cf279%2Cf280%2Cf281%2Cf282&ut=b2884a393a59ad64002292a3e90d46a5&_=1641268581776"
With CreateObject("MSXML2.XMLHTTP")
.Open "GET", URL, False
.send
strText = .responseText
End With
'判断是有null,解决深A股和上A股网址不同拼接问题,secids=0.是深A;secids=1.是上A。
Dim regStrTest As Object
With CreateObject("VBScript.Regexp")
.Pattern = "null"
Set regStrTest = .Execute(strText)
End With
If regStrTest.Count > 0 Then
'如果出现null则拼接构造一个新网址
URL = "https://push2.eastmoney.com/api/qt/ulist.np/get?cb=fltt=2&secids=0." + stock_code + "&fields=f62%2Cf184%2Cf66%2Cf69%2Cf72%2Cf75%2Cf78%2Cf81%2Cf84%2Cf87%2Cf64%2Cf65%2Cf70%2Cf71%2Cf76%2Cf77%2Cf82%2Cf83%2Cf164%2Cf166%2Cf168%2Cf170%2Cf172%2Cf252%2Cf253%2Cf254%2Cf255%2Cf256%2Cf124%2Cf6%2Cf278%2Cf279%2Cf280%2Cf281%2Cf282&ut=b2884a393a59ad64002292a3e90d46a5&_=1641268581776"
With CreateObject("MSXML2.XMLHTTP")
.Open "GET", URL, False
.send
strText = .responseText
End With
End If
Rnum = cl.Row '股票名称所在行号
'利用正则表达式得到我们想要的内容,并写相应的表格
With CreateObject("VBScript.Regexp")
.Pattern = """f62"":(.*?),"
Cells(Rnum, 2) = Round(.Execute(strText)(0).submatches.Item(0) / 100000000, 2) '主力净流进
.Pattern = """f184"":(.*?),"
Cells(Rnum, 3) = Round(.Execute(strText)(0).submatches.Item(0) / 100, 2) '主力净比
.Pattern = """f66"":(.*?),"
Cells(Rnum, 4) = Round(.Execute(strText)(0).submatches.Item(0) / 100000000, 2) '超大单净流进
.Pattern = """f69"":(.*?),"
Cells(Rnum, 5) = Round(.Execute(strText)(0).submatches.Item(0) / 100, 2) '超大单净比
.Pattern = """f72"":(.*?),"
Cells(Rnum, 6) = Round(.Execute(strText)(0).submatches.Item(0) / 100000000, 2) '大单净流进
.Pattern = """f75"":(.*?),"
Cells(Rnum, 7) = Round(.Execute(strText)(0).submatches.Item(0) / 100, 2) '大单净比
.Pattern = """f78"":(.*?),"
Cells(Rnum, 8) = Round(.Execute(strText)(0).submatches.Item(0) / 100000000, 2) '中单净流进
.Pattern = """f81"":(.*?),"
Cells(Rnum, 9) = Round(.Execute(strText)(0).submatches.Item(0) / 100, 2) '中单净比
.Pattern = """f84"":(.*?),"
Cells(Rnum, 10) = Round(.Execute(strText)(0).submatches.Item(0) / 100000000, 2) '小单净流进
.Pattern = """f87"":(.*?),"
Cells(Rnum, 11) = Round(.Execute(strText)(0).submatches.Item(0) / 100, 2) '小单净比
.Pattern = """f64"":(.*?),"
Cells(Rnum, 12) = Round(.Execute(strText)(0).submatches.Item(0) / 100000000, 2) '超大单流入
.Pattern = """f65"":(.*?),"
Cells(Rnum, 13) = Round(.Execute(strText)(0).submatches.Item(0) / 100000000, 2) '超大流出
.Pattern = """f70"":(.*?),"
Cells(Rnum, 14) = Round(.Execute(strText)(0).submatches.Item(0) / 100000000, 2) '大单流入
.Pattern = """f71"":(.*?),"
Cells(Rnum, 14) = Round(.Execute(strText)(0).submatches.Item(0) / 100000000, 2) '大单流出
End With
Next
Application.DisplayAlerts = True
End Sub
这个项目用到的几个重要知识:
- 获取动态网页加载数据的真正网址;
- 使用CreateObject("MSXML2.XMLHTTP")对象获取网页信息,基本框架可以参考用VBA下载一部完整小说;
- 使用CreateObject("VBScript.Regexp")正则表达式对象,处理网页信息并写入表格;
- 点击按钮调用函数
获取动态网页加载数据的真正网址
我们在目标网页点击右键,并点击“查看网页源代码”后,当使用cttl+f键查看我们想要获取的信息进行查看(这里我输入主力净比数据-42.76),发现并没有相关的数据。
在源代码网页同时按cttl+f键查看
通过这个方法基本可以判断目标网页的部分数据是使用动态加载的方式。简单的动态加载数据,可以通过以下两步获取真正的网址:
第一步:打开浏览器控制台。演示使用的浏览器是chrome,按下F12键打开浏览器控制台,再次刷新网页,在控制台找到并点击扩大镜小按钮,打开search对话框,这里输入想找的数据(这里我输入主力净比数据42.76)后,按下回车键或输入框旁边的刷新按键,就会弹出一个“get”字符及一些类似网址的内容,点击弹出的内容,右下面对话框会弹出相应的内容(对话框的菜单有Headers,Preview,Response……)
图中主力净比数据为-42.73和在输入框的数据不一致,是因为资金数据动态变化了
第二步:找到加载数据的网址。点击Headers可以看到Resquest URl字符,后面网址就是加载数据真正的网址,复制网址在浏览器打开,我们可以看到相应的数据内容。获得这网址后,就可以通过VBA访问这个网址获取相应的数据,按下来的工作就好办了。
目标数据的网址
使用CreateObject("MSXML2.XMLHTTP")对象获取网页信息
stock_code = Right(cl, 6) '取右边6位字符
Dim strText, stcok_code As String '
'拼接构造网址
URL = "https://push2.eastmoney.com/api/qt/ulist.np/get?cb=fltt=2&secids=1." + stock_code + "&fields=f62%2Cf184%2Cf66%2Cf69%2Cf72%2Cf75%2Cf78%2Cf81%2Cf84%2Cf87%2Cf64%2Cf65%2Cf70%2Cf71%2Cf76%2Cf77%2Cf82%2Cf83%2Cf164%2Cf166%2Cf168%2Cf170%2Cf172%2Cf252%2Cf253%2Cf254%2Cf255%2Cf256%2Cf124%2Cf6%2Cf278%2Cf279%2Cf280%2Cf281%2Cf282&ut=b2884a393a59ad64002292a3e90d46a5&_=1641268581776"
With CreateObject("MSXML2.XMLHTTP")
.Open "GET", URL, False
.send
strText = .responseText
End With
'判断是有null,解决深A股和上A股网址不同拼接问题,secids=0.是深A;secids=1.是上A。
Dim regStrTest As Object
With CreateObject("VBScript.Regexp")
.Pattern = "null"
Set regStrTest = .Execute(strText)
End With
If regStrTest.Count > 0 Then
'如果出现null则拼接构造一个新网址
URL = "https://push2.eastmoney.com/api/qt/ulist.np/get?cb=fltt=2&secids=0." + stock_code + "&fields=f62%2Cf184%2Cf66%2Cf69%2Cf72%2Cf75%2Cf78%2Cf81%2Cf84%2Cf87%2Cf64%2Cf65%2Cf70%2Cf71%2Cf76%2Cf77%2Cf82%2Cf83%2Cf164%2Cf166%2Cf168%2Cf170%2Cf172%2Cf252%2Cf253%2Cf254%2Cf255%2Cf256%2Cf124%2Cf6%2Cf278%2Cf279%2Cf280%2Cf281%2Cf282&ut=b2884a393a59ad64002292a3e90d46a5&_=1641268581776"
With CreateObject("MSXML2.XMLHTTP")
.Open "GET", URL, False
.send
strText = .responseText
End With
End If
上面代码的说明:
1、使用right(目标字符串,字符个数)函数获取目标字符串从右边数起第几个字符。
2、做两次网址请求是因为深A股和上A股的数据网址是有区别,网址的参数“secids=0.+ 股票代码”是深A;“secids=1.+股票代码”是上A。如果人为对每支股票判断是上A还深A会很复杂,所以使用正则表达式,对请求数据内容出现“null”字样的网址,则更换网址参数。如下图:
上A网址请求结果
深A网址请求结果
使用CreateObject("VBScript.Regexp")正则表达式对象获取数据
For Each cl In Range("a2:a" & Range("a2").End(xlDown).Row)
……
Rnum = cl.Row '股票名称所在行号
'利用正则表达式得到我们想要的内容,并写相应的表格
With CreateObject("VBScript.Regexp")
.Pattern = """f62"":(.*?)," 'VBA的英文的双引号
Cells(Rnum, 2) = Round(.Execute(strText)(0).submatches.Item(0) / 100000000, 2) '主力净流入
.Pattern = """f184"":(.*?),"
Cells(Rnum, 3) = Round(.Execute(strText)(0).submatches.Item(0) / 100, 2) '主力净比
.Pattern = """f66"":(.*?),"
……
上面代码的说明:
1、Range("a2").End(xlDown)是表示定位从A2单元往下最后一个不空值的单元格。
2、cl.Row是表示单元格的行数,Range("A1").Row,Cells(1, 1).Row都可以获取单元格行数,列值则是Range("A1").Column和Cells(1, 1).Column。
3、.Pattern = """f62"":(.*?)," 是正则表达式(网页的内容是:"f62":-15043563520.0),VBA的英文的双引号用正则表式表示则是两个双引号,即是""。"f62":后面数据就是主力净流入的数据,用(.*?)表示。再用.submatches.Item(0)得到目标数据,这个数据是以元为单位,网页显示的是亿,所以要/100000000。
4、Round(目标数据,小数点位数)是取多少位小数的方法。
点击按钮调用函数
Private Sub CommandButton1_Click()
Call maincapital '调用函数
End Sub
在这总结一下VBA抓取数据主要步骤:
分析网站->>分析网页数据->>处理网页数据->>储存网页数据
欢迎大家评论及提意见,相互学习,提高效率,创造价值。
版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站不拥有所有权,不承担相关法律责任。如发现有侵权/违规的内容, 联系QQ15101117,本站将立刻清除。