VBA结合SeleniumBasic实现办公自动化:网页数据抓取与Excel整合实战

1. 项目概述:当VBA遇见SeleniumBasic

如果你和我一样,常年和Excel、Word、PPT打交道,那你一定对VBA(Visual Basic for Applications)又爱又恨。爱的是,它确实能帮我们处理很多重复性的报表整理、数据清洗工作,把我们从“表哥表姐”的苦海中稍微解放出来一点。恨的是,它的能力边界太明显了——VBA本质上是个“办公室宅男”,它最擅长在Office套件内部折腾,一旦需要它走出办公室,去网页上抓个数据、去外部系统里填个表单,它就立刻显得力不从心。你得调用各种复杂的API,处理千奇百怪的验证码和动态加载,代码写起来又长又容易出错。

所以,当几年前我第一次接触到 SeleniumBasic 这个项目时,感觉就像给VBA这位老将配上了一套外骨骼装甲。Selenium本身是Web自动化测试领域的王者,用它可以模拟真人操作浏览器,点击、输入、下拉、截图,无所不能。而SeleniumBasic,简单来说,就是为VBA环境量身打造的一个Selenium客户端库。它让你能在VBA里,直接调用Selenium的强大功能,去控制Chrome、Firefox、Edge这些主流浏览器。

这带来的改变是革命性的。想象一下这些场景:你每天需要从十几个不同的内部管理网站导出销售数据,然后手工复制粘贴到Excel里做分析;或者,公司新上了一套Web版的报销系统,你每个月都要手动录入上百张发票信息;再或者,你需要定时监控某个竞品网站的价格变动。以前,这些要么靠人力,要么得请IT部门开发专门的爬虫或接口,周期长、成本高。现在,你坐在自己的工位上,用你最熟悉的Excel VBA,写几十行代码,就能让浏览器自动完成所有这些操作。数据自动抓取、自动填入Excel指定位置,甚至自动生成图表和报告。这就是 “办公自动化的智能革命” 的核心——将外部Web世界的海量信息和交互能力,无缝接入我们最熟悉的Office生产力工具中,实现内外数据的自动流转与处理。

2. 核心原理与工具选型解析

2.1 为什么是SeleniumBasic,而不是其他?

在VBA里操作浏览器,并不是只有SeleniumBasic一条路。常见的还有:

  1. IE对象(InternetExplorer.Application) :这是VBA“祖传”的方法。但IE浏览器本身已被淘汰,对现代网页(大量使用JavaScript、CSS3)的支持极差,速度慢且不稳定。
  2. WinHttp或XMLHTTP对象 :这类方法直接发送HTTP请求获取网页源码。它的优点是速度快,但缺点是无法处理JavaScript渲染的页面。现在绝大多数网站都是动态加载内容,你用这种方法拿到的经常是一个没有数据的空壳HTML。
  3. 第三方COM组件或付费工具 :这类工具通常封装较好,但可能收费,且灵活性和社区支持不如开源项目。

SeleniumBasic的优势 就在于它找到了一个完美的平衡点:

  • 协议级支持 :它通过WebDriver协议与浏览器通信。这是W3C标准,意味着浏览器厂商(如Google、Microsoft)自己就必须实现并维护这套接口,所以兼容性和稳定性是最好的。
  • 真实浏览器环境 :它驱动的是你电脑上真实的Chrome或Firefox。这意味着网页所有的JavaScript、CSS、Cookie、Session都会正常加载和执行,和你手动打开浏览器看到的效果一模一样。
  • VBA原生集成 :SeleniumBasic被封装成一个标准的VBA引用库( .dll .tlb )。你在VBA编辑器里添加引用后,就能像使用 Excel.Application Scripting.Dictionary 一样,使用 New WebDriver 来创建浏览器对象,语法非常自然。
  • 强大的元素定位能力 :它提供了多达8种元素定位方式(ID、Name、XPath、CSS Selector等),让你能精准地找到页面上的任何一个按钮、输入框或数据表格。

注意 :SeleniumBasic本质上是一个“桥梁”。它本身不包含浏览器驱动(如chromedriver.exe)。你需要根据你电脑上安装的浏览器版本,去下载对应的驱动,并放在SeleniumBasic指定的目录或系统PATH路径下。这是新手最容易卡住的第一步。

2.2 环境搭建与核心对象模型

动手之前,我们需要把环境搭好。整个过程就像组装一台机器,步骤清晰,一步都不能错。

第一步:安装SeleniumBasic 去GitHub上找到 SeleniumBasic 项目,下载最新的发布版本(通常是一个 .exe 安装包)。直接运行安装,它会将必要的库文件注册到你的系统。安装完成后,你的电脑上会多出一个文件夹,里面包含了SeleniumBasic的核心库文件。

第二步:准备浏览器驱动 这是关键。假设我们用Chrome。

  1. 打开Chrome,在地址栏输入 chrome://settings/help ,查看你的Chrome版本号(例如, 120.0.6099.110)。
  2. 打开ChromeDriver的官方下载网站。 这里有个大坑 :驱动版本必须与你的Chrome主版本号完全一致(比如都是120)。如果版本不匹配,SeleniumBasic将无法启动浏览器。
  3. 下载对应的 chromedriver.exe
  4. 将下载的 chromedriver.exe 复制到SeleniumBasic的安装目录下(安装时会有提示),或者复制到 C:\Windows\ 目录下,这样系统就能在任何位置找到它。

第三步:在Excel VBA中引用

  1. 打开Excel,按 ALT + F11 进入VBA编辑器。
  2. 点击菜单栏的 工具 -> 引用
  3. 在弹出的列表中,找到并勾选 SeleniumWrapper Type Library 。如果没找到,可以点击 浏览 ,找到SeleniumBasic安装目录下的 .tlb 文件(通常是 SeleniumWrapper.tlb )。
  4. 点击确定,引用就添加成功了。

现在,我们来认识一下最核心的几个对象,这是你编写所有自动化脚本的基石:

  • WebDriver :这是总指挥。你通过 Dim driver As New WebDriver 来创建一个浏览器实例。后续所有操作,如打开网页、查找元素,都通过这个 driver 对象进行。
  • WebElement :代表页面上的一个元素,比如一个按钮 ( <button> )、一个输入框 ( <input> )、一段文字 ( <span> )。当你使用 driver.FindElement 方法后,返回的就是这个对象。你可以对它进行点击 .Click 、输入文本 .SendKeys 、获取属性 .Attribute 等操作。
  • By :这是一个用于辅助定位元素的类。你通常不会直接创建它,而是使用它的静态方法,如 By.ID(“username”) , By.CssSelector(“.btn-submit”) ,来告诉 driver 你要找什么。

一个最简单的“Hello World”脚本看起来是这样的:

Sub TestSeleniumBasic()
    Dim driver As New WebDriver
    driver.Start “chrome”, “” ‘启动Chrome浏览器
    driver.Get “https://www.baidu.com” ‘导航到百度
    
    ‘找到搜索框,输入关键词
    driver.FindElement(By.ID(“kw”)).SendKeys “SeleniumBasic”
    ‘找到“百度一下”按钮并点击
    driver.FindElement(By.ID(“su”)).Click
    
    ‘等待一下,查看结果
    Application.Wait Now + TimeValue(“00:00:05”)
    
    driver.Quit ‘关闭浏览器
End Sub

运行这段代码,你会看到Chrome自动打开,访问百度,搜索关键词,然后关闭。这一刻,你就已经推开了办公自动化新世界的大门。

3. 实战:构建一个网页数据抓取与Excel整合的自动化流程

光说不练假把式。我们来看一个真实的业务场景: 每日自动从某电商后台抓取商品销售数据,并整理到Excel日报模板中

3.1 需求分析与流程设计

假设我们公司有一个自研的电商管理后台,每天需要登录后,在“销售报表”页面,选择昨日日期,导出数据。手动操作需要:登录 -> 点击报表菜单 -> 选择日期 -> 点击查询 -> 等待页面加载 -> 复制表格数据 -> 粘贴到Excel -> 调整格式。

我们的自动化目标是将以上步骤全部用VBA脚本完成,最终在Excel里得到一个格式规整的日报表。流程设计如下:

  1. 启动与导航 :启动浏览器,打开后台登录页。
  2. 登录认证 :自动输入用户名、密码,点击登录。处理可能的验证码(简单图片验证码可考虑OCR组件,复杂滑块验证码则此方案不适用,需评估)。
  3. 页面跳转与交互 :跳转到报表页面,使用脚本操作日期选择器,选择“昨天”的日期,点击查询按钮。
  4. 数据等待与提取 :等待表格数据加载完成,然后逐行、逐列地读取网页表格( <table> )中的数据。
  5. 数据写入与格式处理 :将读取到的数据写入Excel工作表的指定位置,并应用预设的单元格格式、字体、边框。
  6. 清理与报告 :关闭浏览器,在Excel中生成一个简单的日志,记录抓取是否成功、数据行数。

3.2 关键代码实现与难点突破

我们分步拆解其中的关键代码和可能遇到的“坑”。

步骤一:稳健的启动与隐式等待

Dim driver As New WebDriver
driver.Start “chrome”, “” ‘第二个参数可以指定浏览器路径,留空则用系统默认
driver.Timeouts.PageLoad = 30000 ‘设置页面加载超时为30秒
driver.Timeouts.ImplicitWait = 10000 ‘设置隐式等待10秒

实操心得 ImplicitWait (隐式等待)非常重要。它告诉driver,在查找元素时,如果立即没找到,不要马上报错,而是轮询查找,最多等10秒。这能有效解决因网络或脚本延迟导致的元素未加载问题。

步骤二:登录与可能存在的验证码处理

driver.Get “https://后台登录地址”
driver.FindElement(By.ID(“userName”)).SendKeys “your_username”
driver.FindElement(By.ID(“password”)).SendKeys “your_password”

‘ — 处理简单验证码(假设验证码图片id为’captchaImg’,输入框id为’captcha’)—
‘ 此方法仅适用于字符型验证码,且需要额外OCR库支持,仅供参考思路
‘ Dim captchaElement As WebElement
‘ Set captchaElement = driver.FindElement(By.ID(“captchaImg”))
‘ captchaElement.CaptureScreenshot “C:\temp\captcha.png”
‘ ‘ 调用本地或云OCR API识别图片中的文字,得到code
‘ Dim captchaCode As String
‘ captchaCode = YourOCRFunction(“C:\temp\captcha.png”) ‘ 假设的OCR函数
‘ driver.FindElement(By.ID(“captcha”)).SendKeys captchaCode
‘ — 处理结束 —

driver.FindElement(By.CssSelector(“.login-btn”)).Click ‘点击登录按钮

重要提示 :如果网站验证码非常复杂(如滑块、点选),纯Selenium方案很难破解。此时应考虑:

  1. 联系系统管理员,为自动化账号申请免验证码IP白名单或API接口。
  2. 使用商业验证码识别服务(有成本)。
  3. 手动干预一次,然后使用浏览器Cookie持久化功能,避免下次登录。SeleniumBasic可以获取和设置Cookie: driver.GetCookie(“session_id”) , driver.AddCookie “name”, “value”, “domain”

步骤三:操作日期选择器等复杂交互 很多后台的日期选择器是JavaScript组件,直接输入可能无效。我们需要模拟点击操作。

‘ 假设日期输入框点击后会弹出日历层
driver.FindElement(By.ID(“reportDate”)).Click ‘点击输入框,弹出日历
Application.Wait Now + TimeValue(“00:00:01”) ‘短暂等待日历动画

‘ 方法1:如果日历支持直接输入(input框)
‘ driver.FindElement(By.ID(“reportDate”)).Clear
‘ driver.FindElement(By.ID(“reportDate”)).SendKeys “2023-10-26”

‘ 方法2:更通用的,点击日历上的“昨天”按钮
‘ 需要利用浏览器开发者工具(F12)查看“昨天”按钮的CSS选择器或XPath
driver.FindElement(By.CssSelector(“.calendar-container .yesterday”)).Click

‘ 然后点击查询按钮
driver.FindElement(By.XPath(“//button[contains(text(), ‘查询’)]”)).Click

排查技巧 :如何定位元素?在浏览器页面按F12打开开发者工具,使用“元素选择器”(箭头图标)点击页面上的按钮或输入框,就能在代码区看到其HTML结构。优先使用 ID ,因为它是唯一的。其次用 CSS Selector ,它比 XPath 通常更简洁、性能更好。 XPath 功能强大但写起来复杂,在页面结构变化时更容易失效。

步骤四:等待数据加载并提取表格 点击查询后,数据通常是异步加载的。我们需要“显式等待”某个标志性元素出现。

‘ 显式等待:直到表格的第一行数据出现(假设数据行的CSS类为’.data-row’)
driver.Wait (By.CssSelector(“.data-table tbody tr.data-row”)).Timeout = 15000

‘ 找到整个表格
Dim table As WebElement
Set table = driver.FindElement(By.CssSelector(“.data-table”))

‘ 获取所有行
Dim rows As WebElements
Set rows = table.FindElements(By.TagName(“tr”))

Dim data() As Variant
ReDim data(1 To rows.Count, 1 To 10) ‘假设有10列

Dim i As Long, j As Long
Dim cells As WebElements
For i = 1 To rows.Count
    Set cells = rows(i).FindElements(By.TagName(“td”))
    For j = 1 To cells.Count
        If j <= 10 Then ‘防止列数超出预设
            data(i, j) = cells(j).Text
        End If
    Next j
Next i

这里我们用 driver.Wait 进行显式等待,它比固定的 Application.Wait 更智能,会在条件满足时立即继续,不会浪费不必要的等待时间。

步骤五:将数据写入Excel并格式化

Dim ws As Worksheet
Set ws = ThisWorkbook.Worksheets(“销售日报”)
ws.Cells.ClearContents ‘清空旧数据

‘ 将数组数据一次性写入Excel的A1区域,这比逐个单元格写入快得多
ws.Range(“A1”).Resize(UBound(data, 1), UBound(data, 2)).Value = data

‘ 应用格式:设置标题行背景色、字体加粗、添加边框
With ws.Range(“A1:J1”)
    .Interior.Color = RGB(200, 220, 240)
    .Font.Bold = True
    .Borders.LineStyle = xlContinuous
End With

With ws.UsedRange
    .Borders.LineStyle = xlContinuous
    .HorizontalAlignment = xlCenter
    .VerticalAlignment = xlCenter
End With

性能技巧 :将网页数据先存储到VBA的二维数组 data() 中,然后使用 Range.Value = data 一次性写入工作表,这是最快的操作方式。避免在循环中使用 Cells(i, j).Value = ... ,那会非常慢。

4. 高级技巧与稳定性优化

当你的自动化脚本从demo走向生产环境,每天定时执行时,稳定性就成了生命线。下面分享几个让脚本更健壮的经验。

4.1 异常处理与日志记录

脚本不能一遇到错误就崩溃。我们必须用 On Error GoTo 语句捕获异常。

Sub AutomatedReport()
    On Error GoTo ErrorHandler
    Dim driver As New WebDriver
    Dim logMsg As String
    logMsg = “开始执行: ” & Now
    
    ‘ … 这里是主要的自动化流程代码 …
    
    logMsg = logMsg & vbCrLf & “执行成功: ” & Now
    GoTo CleanUp

ErrorHandler:
    logMsg = logMsg & vbCrLf & “错误发生在: ” & Now & vbCrLf & _
             “错误号: ” & Err.Number & “, 描述: ” & Err.Description
    ‘ 可以尝试截图保存现场,便于排查
    driver.CaptureScreenshot “C:\Logs\error_” & Format(Now, “yyyymmdd_hhmmss”) & “.png”
    
CleanUp:
    ‘ 无论成功失败,都尝试关闭浏览器
    On Error Resume Next ‘防止quit本身出错导致程序中断
    driver.Quit
    Set driver = Nothing
    On Error GoTo 0
    
    ‘ 将日志写入文本文件或Excel的某个隐藏工作表
    WriteLogToFile “C:\Logs\automation.log”, logMsg
End Sub

4.2 处理动态元素与iframe

现代网页大量使用动态ID和iframe(内嵌框架),这对自动化是挑战。

  • 动态ID :如果元素的ID是类似 “button-12345-random” 这样每次刷新都变化的,就不能用 By.ID 。改用其他相对稳定的属性,如 data-testid , name , 或者用 XPath 根据其文本内容或层级关系定位。

    ‘ 使用包含特定文本的XPath
    driver.FindElement(By.XPath(“//button[contains(text(), ‘提交订单’)]”)).Click
    ‘ 使用CSS选择器结合属性
    driver.FindElement(By.CssSelector(“button[data-role=’submit’]”)).Click
    
  • iframe :如果目标元素在一个 <iframe> 里面,你必须先切换到该iframe上下文,才能找到里面的元素。

    ‘ 通过ID或索引切换到iframe
    driver.SwitchToFrame “iframe_id” ‘ 通过ID
    ‘ driver.SwitchToFrame 0 ‘ 通过索引(第一个iframe)
    
    ‘ 现在可以操作iframe内的元素了
    driver.FindElement(By.ID(“innerElement”)).Click
    
    ‘ 操作完成后,切回主页面
    driver.SwitchToDefaultContent
    

4.3 实现无人值守与定时执行

我们希望脚本能在下班后自动运行。有两种主流方法:

  1. Windows任务计划程序

    • 将你的Excel文件另存为一个启用了宏的 .xlsm 文件。
    • 编写一个VBA宏(比如叫 Main ),它包含所有自动化逻辑。
    • 创建一个批处理文件 .bat ,内容如下:
      @echo off
      “C:\Program Files\Microsoft Office\root\Office16\EXCEL.EXE” “D:\你的文件.xlsm” /e /x
      
      /e /x 参数可以让Excel启动后自动运行一个名为 Auto_Open 的宏。所以你需要把你的主逻辑放在一个叫 Auto_Open 的Sub里,或者让 Auto_Open 去调用你的 Main 宏。
    • 在Windows中搜索“任务计划程序”,创建一个新任务,设置触发器(如每天下午6点),操作为启动这个批处理文件。
  2. 在Excel VBA中使用 OnTime 方法

    ‘ 在ThisWorkbook模块中
    Private Sub Workbook_Open()
        ‘ 设置在当前时间的一分钟后执行RunMyTask过程
        Application.OnTime EarliestTime:=Now + TimeValue(“00:01:00”), _
                          Procedure:=“Module1.RunMyTask”, _
                          Schedule:=True
    End Sub
    
    ‘ 在标准模块Module1中
    Public Sub RunMyTask()
        ‘ 调用你的主自动化流程
        Call AutomatedReport
        
        ‘ 设置下一次执行,例如明天同一时间
        Application.OnTime EarliestTime:=Date + 1 + TimeValue(“18:00:00”), _
                          Procedure:=“Module1.RunMyTask”, _
                          Schedule:=True
    End Sub
    

    这种方法需要Excel一直处于打开状态,适合在专用虚拟机或从不关机的办公电脑上运行。

5. 常见问题排查与性能调优实录

即使代码写得再小心,在实际运行中还是会遇到各种问题。下面是我踩过的一些坑和解决方案。

5.1 浏览器驱动版本不匹配

这是最高频的错误。症状是:运行 driver.Start “chrome”, “” 时,弹出一个错误框,或者代码报错“无法创建WebDriver”。

  • 解决方案 :严格按照你Chrome浏览器的版本号,去下载相同主版本号的 chromedriver.exe 。更新Chrome后,务必记得重新下载驱动。

5.2 元素找不到(NoSuchElementError)

代码报错,说找不到某个ID或选择器对应的元素。

  • 排查清单
    1. 等待不足 :元素还没加载出来代码就去找了。增加隐式等待 driver.Timeouts.ImplicitWait ,或在关键操作前使用显式等待 driver.Wait
    2. 定位器写错 :用开发者工具仔细核对元素的ID、Class或XPath是否正确。注意大小写,注意是否有空格。
    3. 元素在iframe或shadow DOM内 :如果是,需要先切换上下文。
    4. 页面有多个匹配项 FindElement 只返回第一个。如果你需要操作第二个,使用 FindElements 获取集合,然后按索引操作。
    5. 页面结构已变更 :网站改版了。这是自动化脚本的“天敌”,需要定期维护更新定位器。

5.3 脚本执行速度慢

感觉浏览器操作一卡一卡的,整体运行时间很长。

  • 性能调优点
    • 减少不必要的等待 :用智能的 driver.Wait 替代固定的 Application.Wait
    • 关闭浏览器不必要的功能 :启动浏览器时可以添加参数,提升速度。
      driver.Start “chrome”, “–disable-gpu –no-sandbox –disable-dev-shm-usage –disable-extensions”
      
      –disable-gpu 在无头模式下有用; –no-sandbox 在某些Linux环境下需要; –disable-dev-shm-usage 解决共享内存问题; –disable-extensions 禁用扩展。
    • 使用无头模式 :如果不需要看到浏览器界面,使用无头模式可以极大节省资源。
      driver.Start “chrome”, “–headless”
      
    • 批量操作 :如之前所述,数据写入Excel使用数组一次性操作。

5.4 浏览器被检测为自动化工具

一些高级网站(如某些登录门户、反爬严格的站点)会检测浏览器是否被Selenium等工具控制。症状是登录失败,或者跳转到验证页面。

  • 应对策略
    • 使用 chromeOptions 排除检测特征 :这是比较有效的方法。SeleniumBasic可以通过 AddArgument 添加参数。
      Dim options As New ChromeOptions
      options.AddArgument “–disable-blink-features=AutomationControlled”
      options.AddExcludedSwitch “enable-automation”
      options.AddAdditionalCapability “useAutomationExtension”, False
      
      Dim driver As New WebDriver
      driver.Start “chrome”, “”, options
      
    • 更彻底的方法 :使用第三方工具如 undetected-chromedriver ,但它与VBA集成较复杂,可能需要通过命令行间接调用。

5.5 内存泄漏与浏览器未关闭

脚本跑久了,或者异常退出时,可能会留下浏览器进程和驱动进程,占用内存。

  • 健壮性设计
    Sub SafeAutomation()
        Dim driver As WebDriver
        On Error GoTo CleanUp
        Set driver = New WebDriver
        ‘ … 你的代码 …
        
    CleanUp:
        If Not driver Is Nothing Then
            On Error Resume Next
            driver.Quit ‘ 尝试正常退出
            ‘ 如果正常退出失败,强制结束进程(Windows API)
            Dim pid As Long
            pid = driver.ProcessId ‘ SeleniumBasic 2.0+ 支持
            If pid > 0 Then
                Shell “taskkill /f /pid ” & pid, vbHide
            End If
            Set driver = Nothing
        End If
    End Sub
    
    可以在脚本开始和结束时,记录系统进程列表,如果发现残留的 chromedriver.exe chrome.exe 进程,就用 taskkill 命令强制结束。

将SeleniumBasic引入你的VBA工具箱,绝不是简单地多学一个库。它本质上是扩展了VBA的能力边界,让你能从“办公室”走向“整个互联网”。最初,你可能会花不少时间在调试元素定位器和处理网页异步加载上,这很正常。我的建议是,从一个最小、最确定的任务开始,比如只是打开网页、登录、然后截图。成功了,再一点点增加复杂度。当你成功地将第一个网页数据流自动灌入Excel,并看着它自动生成图表时,那种成就感会让你觉得所有的调试都是值得的。这个技术栈最妙的地方在于,它把强大的Web自动化能力,封装成了你早已熟悉的VBA语法,学习曲线相对平缓,但带来的效率提升是指数级的。

内容概要:本文介绍了一个针对电力系统连锁故障传播路径的N-k多阶段双层优化及故障场景筛选模型,该模型基于混合整数线性规划(MILP)方法构建,旨在全面评估电力系统在遭受多重故障时的脆弱性恢复能力。通过引入故障传播路径的概念,模型能够动态模拟故障在电网中的逐级扩散过程,并结合多阶段优化策略,实现对关键故障场景的有效识别优先排序。整个框架不仅考虑了初始故障元件的选取,还涵盖了后续因潮流转移引发的级联跳闸行为,从而提升了风险评估的准确性时效性。该研究已在Matlab平台上完成代码实现,具备良好的可复现性和工程应用价值,适用于提升现代电网的安全防御水平。; 适合人群:电力系统、能源安全及相关领域的科研人员、高校研究生以及从事电网规划运行管理的工程技术人员。; 使用场景及目标:①用于电力系统安全评估中识别最危险的N-k故障组合;②支撑电网应急预案制定薄弱环节改造;③作为学术研究中关于级联故障建模优化求解的教学验证工具;④服务于智能电网背景下抵御蓄意攻击或极端事件的风险防控决策。; 阅读建议:建议读者结合Matlab代码深入理解模型的数学 formulation 求解流程,重点关注目标函数设计、约束条件构建及双层优化结构的实现逻辑,同时可通过调整系统参数和故障设定进行仿真对比分析,以掌握不同因素对连锁故障演化的影响规律。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值