ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

搜索
EH技术汇-专业的职场技能充电站 妙哉!函数段子手趣味讲函数 Excel服务器-会Excel,做管理系统 效率神器,一键搞定繁琐工作
HR薪酬管理数字化实战 Excel 2021函数公式学习大典 Excel数据透视表实战秘技 打造核心竞争力的职场宝典
让更多数据处理,一键完成 数据工作者的案头书 免费直播课集锦 ExcelHome出品 - VBA代码宝免费下载
用ChatGPT与VBA一键搞定Excel WPS表格从入门到精通 Excel VBA经典代码实践指南
查看: 7110|回复: 12

[求助] 关于网页、浏览器操作控制的研究探讨

[复制链接]

TA的精华主题

TA的得分主题

发表于 2018-12-15 13:19 | 显示全部楼层 |阅读模式
访问网站、解析页面最简单的就是使用WebBrowser控件,不过XP支持的最高是IE8,WIN7-10 最高的IE版本是11,以后的IE将不再更新,WIN10系统以后只专注开发Edge浏览器。
使用WebBrowser控件与直接获得IE浏览器对象后直接控制的方法都是一样,在获得DOM对象以后可以很方便的对网页中每一个元素操作,实现自动化操作方便。
WebBrowser控件默认使用IE6,需要高版本,应该修改注册表,WebBrowser控件的弊病就是内存消耗大,碰到过打开几百次网页操作后内存耗尽,用IE浏览器则没有这个问题。
下面是直接控制IE浏览器的语句例子:新建浏览器对象(不使用已经打开的浏览器),访问百度
Set objIE = CreateObject("InternetExplorer.Application")'如果装有360等双内核浏览器,请先解除默认,才能正确打开IE
objIE .navigate "www.baidu.com"
如果要用已经打开的浏览器访问百度,先找到浏览器对象,然后调用(这个方法可以获得当前IE正在浏览的网页及所有操作)
Set objShell = CreateObject("Shell.Application") '建立外壳对象
Set objShellWindows = objShell.windows '所有窗口对象
For Each objwindow In objShellWindows '查找IE对象
    If InStr(1, objwindow.FullName, "IEXPLORE.EXE", vbTextCompare) <> 0 Then'如果是浏览器
        objwindow.navigate "www.baidu.com"
        Exit For
    End If
Next
还有一种是ie浏览器使用多个标签模式,比较麻烦,无法用建立CreateObject或者获得getObject对象的语句去获得当前浏览器已经打开的网页窗口,需要自己用API注册一个浏览器对象。
如果自己POST、GET网址,可以用 CreateObject("htmlfile")来解析页面元素,Set objHtmlfile = CreateObject("htmlfile")
由于与操作系统绑定的关系,IE内核的浏览器速度慢,效率低,如何使用VBA对其它的浏览器操作,是目前研究方向。
用selenium可以很方便对各种浏览器调用,可惜VBA使用不了。通过研究分析Selenium 的WebDriver,发现它只是与浏览器通讯然后对它操作控制,不是使用COM对象等调用方式。
原理是在本机开启一个端口,把浏览器当作一个服务器,对指定端口POST发送数据指令就可以完美控制浏览器操作。
关于火狐浏览器的调用,需要安装一个MozRepl的插件,这个插件启动后会打开4242端口,向这个端口post数据,从而控制火狐浏览器,及对元素信息获得及操作,
而chrome谷歌浏览器需要下载一个chromedriver.exe的文件,运行后会打开9515端口,然后向这个端口post数据即可控制浏览器,对元素信息获得及操作。
不同版本的chrome浏览器需要不同chromedriver驱动,下载地址:http://chromedriver.storage.googleapis.com/index.html

对浏览器发送的指令有详细的规范,目前的碰到难题是不知道如何向指定端口POST数据,请懂的网友共同研究一下。
下面是我找到的参考资料
打开浏览器:
请求方式 :POST
请求地址 :http://localhost:9515/session
请求body :{"capabilities": {"firstMatch": [{}], "alwaysMatch": {"browserName":     "chrome", "platformName": "any", "goog:chromeOptions": {"extensions": [], "args": []}}},
"desiredCapabilities": {"browserName": "chrome", "version": "", "platform": "ANY", "goog:chromeOptions": {"extensions": [], "args": []}}}

操作相关的接口详细文档
https://github.com/SeleniumHQ/selenium/wiki/JsonWireProtocol

TA的精华主题

TA的得分主题

发表于 2018-12-15 14:15 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
试了下应该是可行的。但是使用vba的话需要不停的换url并且get and post各种参数,委实麻烦啊。

TA的精华主题

TA的得分主题

发表于 2018-12-15 15:46 | 显示全部楼层

TA的精华主题

TA的得分主题

 楼主| 发表于 2018-12-15 16:56 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
duquancai 发表于 2018-12-15 15:46
这些东东 过时了!!!

这些东东完全没有过时,估计你还不了解这方面的技术,只要浏览器存在一天,这东西都不会过时。
而且,

直到现在,全网络上都没有一篇讲解VBA调用chrome浏览器的技术帖子。

在办公自动化方面,随着C/S退出江湖,越来越多公司采用B/S架构,以后录入数据不再是软件+数据库(C/S)方式,被浏览器取代,而IE浏览器正在被逐渐抛弃,所以我才转入研究chrome浏览器自动化操作,目前研究工作遇到了瓶颈,所以来这里请教大神们的支持,只要能跨出第一步,POST打开浏览器,后面的工作都简单了。

再一次请教大神支持。

TA的精华主题

TA的得分主题

发表于 2019-3-1 23:20 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
兄弟,好思路,一起搞搞!~

TA的精华主题

TA的得分主题

 楼主| 发表于 2019-4-7 10:39 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
在我发这个求助帖子之前,没有找到VBA调用chrome浏览器的例子,不过从网友“源理”的帖子《vba中使用Selenium 》http://club.excelhome.net/thread-1452021-6-1.html这个问题就已经解决了,也不知道如何结帖。

请帮忙结帖。

Selenium能够调用浏览器,是遵循了WebDriver的规范,如果想绕开Selenium,也是可以的。
如果要完整的完成一套动作,也就相当于自己写了类似于Selenium的驱动,这是个浩大的工程。
所以,想来想去,还是使用现成的。

下面自己写了一段测试代码,就是按WebDriver的规范,打开浏览器,访问百度的例子。
首先启动chromedriver.exe(会打开9515端口),然后运行下面代码
捕获.JPG
'打开百度
OpenChrome "http://www.baidu.com"

Private Sub OpenChrome(mBaseLocalURL  as string)
    Dim Webcode$, Url$, PostDate$
    Dim LocalURL As String
mPort = 9515
    LocalURL = mBaseLocalURL & ":" & mPort & "/session"
'    PostDate = "{‘capabilities‘: {‘firstMatch‘: [{}], ‘alwaysMatch‘: {‘browserName‘:     ‘chrome‘, ‘platformName‘: ‘any‘, ‘goog:chromeOptions‘: {‘extensions‘: [], ‘args‘: []}}}, " & _
' "‘desiredCapabilities‘: {‘browserName‘: ‘chrome‘, ‘version‘: ‘‘, ‘platform‘: ‘ANY‘, ‘goog:chromeOptions‘: {‘extensions‘: [], ‘args‘: []}}}"
'    PostDate = Replace(PostDate, "‘", Chr(34))
'    Debug.Print PostDate
    PostDate = ("{capabilities:{firstMatch=[{}],alwaysMatch:{browserName='chrome',platformName='any','goog:chromeOptions':{extensions:[],args:[]}}},desiredCapabilities:{browserName='chrome',version='',platform='ANY','goog:chromeOptions':{extensions=[],args=[]}}}")
    PostDate = GetVbStringToJSON(PostDate)
'Debug.Print PostDate
    Webcode = XMLHttpRequest("POST", LocalURL, PostDate)
    Webcode = Replace(Webcode, Chr(34), "")
    mSessionId = GetKeyWordMid(Webcode, "sessionId:", ",")
    Debug.Print mSessionId
End Sub

Private Function XMLHttpRequest(ByVal XmlHttpMode$, ByVal XmlHttpURL$, ByVal XmlHttpData$) As String
    Dim MyXmlhttp
    On Error GoTo wrong
'    Set MyXmlhttp = CreateObject("WinHttp.WinHttpRequest.5.1")                  '创建WinHttpRequest对象
    Set MyXmlhttp = CreateObject("MSXML2.ServerXMLHTTP")
    With MyXmlhttp
        .setTimeouts 50000, 50000, 50000, 50000                                 '设置超时时间
        If XmlHttpMode = "GET" Then                                             '异步GET请求
            .Open "GET", XmlHttpURL, True
        Else
            .Open "POST", XmlHttpURL, False                                      '异步POST请求
'            .setRequestHeader "Content-Type", "application/x-www-form-urlencoded"
        End If
        '无Http头信息
        .Send (XmlHttpData)
        .waitForResponse                                                        '异步等待
        If MyXmlhttp.Status = 200 Then                                          '成功获取页面
            XMLHttpRequest = StrConv(.ResponseBody, vbUnicode)
        Else
            MsgBox "Http错误代码:" & .Status, vbInformation, "提示"
        End If
    End With
    Set MyXmlhttp = Nothing
    Exit Function
wrong:
Debug.Print Err.Description, "ddd", vbInformation
    MsgBox "错误原因:" & Err.Description & "", vbInformation, "提示"
    Set MyXmlhttp = Nothing
End Function

Private Function GetVbStringToJSON(NameAndValue As String)
Dim i As Long
Dim FlagNot As Boolean, StartStatus As Long
Dim strBuffer As String
Dim tmpMid As String

For i = 1 To Len(NameAndValue)
    tmpMid = Mid(NameAndValue, i, 1)
    Select Case tmpMid
        Case "'"
            FlagNot = Not FlagNot
            If FlagNot Then
                StartStatus = 0
            End If
            strBuffer = strBuffer & Chr(34)
        Case "{"
            StartStatus = 1
            strBuffer = strBuffer & tmpMid
        Case ":", "="
            If FlagNot Then
                strBuffer = strBuffer & tmpMid
            Else
                If StartStatus = 2 Then
                    strBuffer = strBuffer & Chr(34)
                    StartStatus = 0
                End If
                strBuffer = strBuffer & ":"
            End If
        Case ","
            If FlagNot Then
                strBuffer = strBuffer & tmpMid
            Else
                strBuffer = strBuffer & tmpMid
                StartStatus = 1
            End If
        Case "[", "]", "}", Chr(32)
            strBuffer = strBuffer & tmpMid
        Case Else
            If StartStatus = 1 Then
                strBuffer = strBuffer & Chr(34)
                strBuffer = strBuffer & tmpMid
                StartStatus = 2
            Else
                strBuffer = strBuffer & tmpMid
            End If
    End Select
Next

GetVbStringToJSON = strBuffer
End Function
Private Function GetKeyWordMid(InputStr, StrKey1 As String, StrKey2 As String, Optional Start As Long = 1) As String
'取两个关键字之间的内容
Dim nLen As Long
Dim nFind1 As Long
Dim nFind2 As Long

nLen = Len(InputStr)
nFind1 = InStr(Start, InputStr, StrKey1) '查找第一个关键字
nFind2 = InStr(nFind1 + 1, InputStr, StrKey2) '在找到的第一个关键字后一位开始找第二个关键字
If nFind1 > 0 And nFind2 - nFind1 > 1 Then '如果找到,而且第二个关键字位置大于第一个。
    GetKeyWordMid = Mid(InputStr, nFind1 + Len(StrKey1), nFind2 - nFind1 - Len(StrKey1))
End If
End Function


TA的精华主题

TA的得分主题

发表于 2020-7-3 22:33 | 显示全部楼层
大神您好,我用您的方法打开了网站,很是兴奋。现在我想把一些信息用VBA输入到网页上,请问如何把信息填充到网页上呢,比如将发票代码、发票号码等信息填入网页中,验证码的话就需要自己填了,VBA应该是看不出来的。谢谢您啦
发票验真.jpg
网页代码.png
打开网页代码.jpg

TA的精华主题

TA的得分主题

 楼主| 发表于 2020-7-4 13:34 | 显示全部楼层
在https://vb6.lanzous.com/i9lopcb下载《vb操作谷歌浏览器》的压缩包,这个压缩包中的代码演示了启动浏览器,打开百度,输入“mp3”,然后点击“搜索”的一套完整动作。可以参考一下。里面的frmMain.frm是一个测试窗体,可以用文本文件直接打开看代码。
把类模块cWebDriver.cls加载到你的表格。对于你发的网址,发票代码输入框的xpath为://*[@id="fpdm"],所以只要引用下面的代码就可以在输入框中输入数据了。
  1. strID = web.GetElementID("//*[@id='fpdm']") '获得输入框的元素ID
  2. web.ElementValue strID, "123456"       '输入发票代码 123456
复制代码
查找想path的方法如图

捕获.JPG



TA的精华主题

TA的得分主题

 楼主| 发表于 2020-7-4 13:50 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
如果按你的代码,
发票代码:getElementById("fpdm")
发票号码:getElementById("fphm")
开票日期:getElementById("kprq")
开具金额(不含税):getElementById("kjje")
验证码:getElementById("yzm")

或者:
发票代码:getElementsByName("INPUT")(0)
发票号码:getElementsByName("INPUT")(1)
开票日期:getElementsByName("INPUT")(2)
开具金额(不含税):getElementsByName("INPUT")(3)
验证码:getElementsByName("INPUT")(4)
都可以获得元素

验证码解决:自己找个打码的平台解一下或者用插件。
如果输入框检测键盘动作,可以用sendkeys语句整一下,或者是模拟激活输入事件都行。

TA的精华主题

TA的得分主题

发表于 2020-8-18 21:56 | 显示全部楼层
有么有大侠知道如何使用vba控制已经打开的Edge浏览器打开的网页
您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

手机版|关于我们|联系我们|ExcelHome

GMT+8, 2024-11-20 13:32 , Processed in 0.043459 second(s), 9 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

沪公网安备 31011702000001号 沪ICP备11019229号-2

本论坛言论纯属发表者个人意见,任何违反国家相关法律的言论,本站将协助国家相关部门追究发言者责任!     本站特聘法律顾问:李志群律师

快速回复 返回顶部 返回列表