Excel Selenium操作Investing.com登录后无法点击CSV下载按钮求助
问题:Excel VBA结合Selenium下载Investing.com CSV文件失败
我需要从指定页面下载CSV文件,已经用Excel VBA结合Selenium完成账号密码输入并成功登录,但点击CSV下载按钮时遇到问题,求排查代码问题。
原代码
With dD '.Start .Get Url ' clicca "accetta" dD.FindElementByXPath("//*[@id='onetrust-button-group-parent']").Click Application.Wait (Now + TimeValue("00:00:02")) '---------------------------------------- Login --------------------------------------- ' accedi Set Btn = dD.FindElementByXPath("/html/body/div[1]/header/div[1]/section/div[3]/ul/li[1]/button/span") Btn.Click ' accedi tramite mail Set btn1 = dD.FindElementByXPath("/html/body/div[4]/div/div/form/button[4]/span") btn1.Click ' inserisce user .FindElementByXPath("//*[@id=':rb:']/form/div[3]/input").SendKeys myUser 'inserisce password .FindElementByXPath("//*[@id=':rb:']/form/div[5]/input").SendKeys myPassword ' conferma pulsante accedi Set btn2 = dD.FindElementByXPath("//*[@id=':rb:']/form/button/span") btn2.Click Application.Wait (Now + TimeValue("00:00:01")) ' pulsante accedi Set btn3 = dD.FindElementByXPath("/html/body/div[4]/div/div/form/button") btn3.Click Application.Wait (Now + TimeValue("00:00:10")) '--------------------------------------------- here the error '//*[@id="__next"]/div[2]/div[2]/div[2]/div[1]/div[3]/div[2]/div[2]/div[1]/div/span[2] Set btn4 = dD.FindElementByXPath("//*[@id='__next']/div[2]/div[2]/div[2]/div[1]/div[3]/div[2]/div[2]/div[1]/div/span[2]") btn4.Click ' Set btn4 = dD.FindElementByCss("span.text-center:nth-child(2)") ' btn4.Click '------------------------------------------------------------ fName = myIsin & ".csv" mioFile = Percorso & fName .SaveAs Filename:=mioFile, Local:=False, CreateBackup:=False End With dD.Quit Call ConvertiCSV Set dD = Nothing Set wks = Nothing Set Wks1 = Nothing End Sub
问题排查与修正方案
1. 绝对XPath定位极易失效
你用的是绝对XPath定位下载按钮,这类路径完全依赖页面DOM结构的层级关系,Investing.com的页面结构会动态更新(比如弹窗、组件加载顺序变化),直接导致元素找不到。
应该改用相对定位,比如根据按钮的文本(意大利语的"CSV")、class属性或者图标特征来定位,示例:
' 优先用文本定位,更直观 .FindElementByXPath("//span[contains(text(), 'CSV')]").Click ' 或者用class组合定位(需要对应页面实际class) .FindElementByXPath("//span[contains(@class, 'download-icon') and contains(@class, 'csv')]").Click
2. 等待机制不合理
当前用Application.Wait固定等待时间,完全靠运气赌页面加载完成,很容易出现元素未加载就执行点击的情况。
替换为Selenium的显式等待,等待元素可点击后再操作:
' 等待下载按钮可点击,超时10秒 dD.WaitUntil ElementIsClickable("//span[contains(text(), 'CSV')]", 10000) dD.FindElementByXPath("//span[contains(text(), 'CSV')]").Click
3. 重复登录操作导致页面状态异常
代码里连续点击了两次登录按钮(btn2和btn3),这会导致登录请求重复提交,可能引发页面弹窗、跳转异常,直接删除其中一次即可,保留最后一次点击或者确认按钮的点击。
4. 下载文件处理逻辑缺失
Selenium需要提前配置浏览器的默认下载路径,否则无法直接用.SaveAs获取文件,而且要等待文件下载完成后再执行后续操作:
' 初始化Chrome时配置下载路径(以Chrome为例) Dim chromeOpts As New ChromeOptions chromeOpts.AddArgument "--download.default_directory=" & Percorso ' Percorso是你指定的保存路径 Set dD = New ChromeDriver dD.Start "chrome", chromeOpts ' 登录、点击下载按钮后,等待文件存在 Do While Dir(Percorso & myIsin & ".csv") = "" Application.Wait Now + TimeValue("00:00:01") Loop
修正后的完整代码示例
Sub DownloadInvestingCSV() Dim dD As ChromeDriver Dim chromeOpts As ChromeOptions Dim myUser As String, myPassword As String, Url As String Dim Percorso As String, myIsin As String ' 替换为你的实际参数 myUser = "你的邮箱" myPassword = "你的密码" Url = "https://it.investing.com/rates-bonds/it0005583486-historical-data" Percorso = "C:\你的下载路径\" myIsin = "it0005583486" Set chromeOpts = New ChromeOptions chromeOpts.AddArgument "--download.default_directory=" & Percorso Set dD = New ChromeDriver On Error GoTo Cleanup ' 错误处理 With dD .Start "chrome", chromeOpts .Get Url ' 处理Cookie同意(定位实际的同意按钮) .WaitUntil ElementIsVisible("//*[@id='onetrust-accept-btn-handler']", 10000) .FindElementByXPath("//*[@id='onetrust-accept-btn-handler']").Click ' 点击登录按钮(用文本定位,更稳定) .WaitUntil ElementIsClickable("//header//button[contains(text(), 'Accedi')]", 10000) .FindElementByXPath("//header//button[contains(text(), 'Accedi')]").Click ' 选择邮箱登录 .WaitUntil ElementIsVisible("//button[contains(text(), 'Accedi con email')]", 10000) .FindElementByXPath("//button[contains(text(), 'Accedi con email')]").Click ' 输入账号密码(用name属性定位,避免动态ID) .WaitUntil ElementIsVisible("//input[@name='email']", 10000) .FindElementByXPath("//input[@name='email']").SendKeys myUser .FindElementByXPath("//input[@name='password']").SendKeys myPassword ' 提交登录 .FindElementByXPath("//button[contains(text(), 'Accedi')]").Click .WaitUntil ElementIsVisible("//*[@id='__next']", 15000) ' 等待登录后页面加载 ' 点击CSV下载按钮 .WaitUntil ElementIsClickable("//span[contains(text(), 'CSV')]", 10000) .FindElementByXPath("//span[contains(text(), 'CSV')]").Click ' 等待文件下载完成 Do While Dir(Percorso & myIsin & ".csv") = "" Application.Wait Now + TimeValue("00:00:01") Loop End With Call ConvertiCSV ' 执行转换逻辑 Cleanup: If Err.Number <> 0 Then MsgBox "错误:" & Err.Description, vbCritical End If dD.Quit Set dD = Nothing Set chromeOpts = Nothing End Sub
内容的提问来源于stack exchange,提问作者gianca53
相关产品推荐
相关产品推荐

