VB通过webbrowser过滤网页元素的函数

简介: VB通过webbrowser过滤网页元素的函数

vb中嵌入网页是通过webbrowser控件来实现的。有时我们需要做自动表单处理,也就是向网页填充数据或者点击按钮选择下拉之类,这些在以前都是通过遍历所有网页元素根据一些条件判断来确定的,虽然webbrowser也有直接的dom接口可以调用document对象,如果有name和id属性还好说,但是如果没有的话仅凭class或者index、data-id等其他属性就比较困难了。

这里我封装了一个函数可以非常方便的过滤,有点像sql语句那样的条件过滤,其中判断是否相等借鉴了jQuery的过滤器语法,例如$=xxx表示末尾是xxx,^=xxx表示开头是xxx等等。

Option Explicit
Private Declare Function SafeArrayGetDim Lib "oleaut32.dll " (ByRef saArray() As Any) As Long
'名称:getElementsByAttributes
'功能:根据一个或多个条件对dom对象所有元素进行过滤得到目标元素
'参数:WebBrowser1,WebBrowser类型,要处理的webbrowser
'      strAttributes,string型,内容为属性列表,多项的话用逗号隔开,
'返回:如果有匹配到的结果那么返回的就是html元素对象数组,用户需要执行判断使用
'范例:g(WebBrowser1,"id='kw'")(0).value="vb" '设置百度搜索框内容为vb
'     g(WebBrowser1,"value='百度一下',type='submit'")(0).click '点击百度的搜索按钮
'     g(WebBrowser1,"tagname='input',value^='百度'")(0).click '得到文本开头为“百度”的按钮并执行点击
'      Dim v
'      For Each v In g(WebBrowser1, "tagname=img,src<>''")
'          Print v.src
'      Next
'作者:sysdzw
'日期:23:53 2017-1-17
Public Function getElementsByAttributes(WebBrowser1 As Object, ByVal strAttributes As String) As Variant
    Dim vTag As Object
    Dim i&, strTiaojians$, strTagValue$, isElementOk As Boolean, intElement%, vrt()
    Dim reg As Object
    Dim matchs As Object
    Dim strAttrName As String, strAttrValue As String
    Set reg = CreateObject("vbscript.regExp")
    reg.Global = True
    reg.IgnoreCase = True
    reg.MultiLine = True
    reg.Pattern = "([a-z\dA-Z-_.]+)([!=<>^$*|~]+)(['""]?)([^,]*)\3"
    Set matchs = reg.Execute(strAttributes)
    For Each vTag In WebBrowser1.Document.All
        isElementOk = True
        For i = 0 To matchs.Count - 1 '循环判断strAttributes中的多个条件,只有都符合才能返回true,如果有一个不符合就返回false并且退出其他条件的判断
            strAttrName = LCase(matchs(i).SubMatches(0))
            If strAttrName = "classname" Then strAttrName = "class"'统一化,因为vTag.getattribute("class")才能取到值,但是如果没有class就会返回null,所以下面还是需要处理下
            If strAttrName = "tagname" Then
                If Not isConditionOk(LCase(vTag.tagname), matchs(i).SubMatches(1), LCase(matchs(i).SubMatches(3))) Then
                    isElementOk = False
                    Exit For
                End If
            ElseIf strAttrName = "innerhtml" Then
                If Not isConditionOk(LCase(vTag.innerhtml), matchs(i).SubMatches(1), LCase(matchs(i).SubMatches(3))) Then
                    isElementOk = False
                    Exit For
                End If
            ElseIf strAttrName = "innertext" Then
                If Not isConditionOk(LCase(vTag.innertext), matchs(i).SubMatches(1), LCase(matchs(i).SubMatches(3))) Then
                    isElementOk = False
                    Exit For
                End If
            Else
                If IsNull(vTag.getattribute(strAttrName)) Then '如果没有设置属性就会返回null,比如没有class或name,但是有时我们也会用到class=''
                    strTagValue = ""
                Else
                    strTagValue = vTag.getattribute(strAttrName)
                End If
                If Not isConditionOk(strTagValue, matchs(i).SubMatches(1), matchs(i).SubMatches(3)) Then
                    isElementOk = False
                    Exit For
                End If
            End If
        Next
        If isElementOk Then
            ReDim Preserve vrt(intElement)
            Set vrt(intElement) = vTag
            intElement = intElement + 1
        End If
    Next
    If SafeArrayGetDim(vrt) = 0 Then
        getElementsByAttributes = Split("", "")
    Else
        getElementsByAttributes = vrt
    End If
End Function
'简略的调用方式
Public Function g(WebBrowser1 As Object, ByVal strAttributes As String) As Variant
    g = getElementsByAttributes(WebBrowser1, strAttributes)
End Function
'根据运算符检查条件是否符合
Private Function isConditionOk(ByVal strTagValue$, ByVal strCondition$, ByVal strValueForCheck$) As Boolean
    If strCondition = "=" Then
        isConditionOk = (strTagValue = strValueForCheck)
    ElseIf strCondition = "!=" Or strCondition = "<>" Then
        isConditionOk = (strTagValue <> strValueForCheck)
    ElseIf strCondition = "^=" Then '选取开头为strValueForCheck的
        isConditionOk = (Left(strTagValue, Len(strValueForCheck)) = strValueForCheck)
    ElseIf strCondition = "$=" Then '选取末尾为strValueForCheck的
        isConditionOk = (Right(strTagValue, Len(strValueForCheck)) = strValueForCheck)
    ElseIf strCondition = "*=" Then '选取包含strValueForCheck的
        isConditionOk = (InStr(strTagValue, strValueForCheck) > 0)
    ElseIf strCondition = "|=" Then '选取值为strValueForCheck或者值为strValueForCheck前缀的,即strValueForCheck后面加个-
        isConditionOk = (InStr(strTagValue, strValueForCheck) > 0 Or InStr(strTagValue, strValueForCheck & "-") > 0)
    ElseIf strCondition = "~=" Then '选取属性值用空格分隔的值中包含给定值的元素
        isConditionOk = (InStr(" " & strTagValue & " ", " " & strValueForCheck & " ") > 0)
    End If
End Function


目录
相关文章
|
5月前
|
JSON 安全 Java
什么是用于REST API的JWT Bearer令牌以及如何通过代码和工具进行调试
在Web开发中,保护REST API至关重要,而JSON Web令牌(JWT)特别是JWT Bearer令牌,是一种高效方法。它通过紧凑、自包含的结构实现安全信息交换,提升用户体验。本文探讨JWT Bearer的基本概念、结构与实现,包括在Java中的应用步骤,以及使用Apipost和cURL进行测试的方法。JWT优势明显:无状态、互操作性强,适用于分布式系统。掌握JWT Bearer,可助开发者构建更安全、高效的API解决方案。
|
缓存 前端开发 NoSQL
设计与实现个人博客系统的技术架构与最佳实践
设计与实现个人博客系统的技术架构与最佳实践
|
Java API 调度
多线程 02
多线程 02
68 0
|
编译器 Go 调度
Go结构体&接口&反射(下)
Go结构体&接口&反射(下)
|
Linux
解决Linux使用fcitx5输入法无法输入问题
解决Linux使用fcitx5输入法无法输入问题
1189 0
解决Linux使用fcitx5输入法无法输入问题
零基础VB教程030期:字符文本处理课题总结
零基础VB教程030期:字符文本处理课题总结
105 0
|
iOS开发
完整版在xcode打测试专用ipa包流程
前言:有时候,想要把自己的程序运行在别人的iphone手机上,但又不能通过本地真机调试的方法安装,这个时候我们就要打一个测试专用的ipa包给远方的测试小伙伴们测试。
|
监控 负载均衡 前端开发
用SkyWalking做分布式追踪和应用性能监控系统
SkyWalking 是观察性分析平台和应用性能管理系统。提供分布式追踪、服务网格遥测分析、度量聚合和可视化一体化解决方案。
1934 0