VBA Selenium - 文本未从 Xpath 拉取

VBA Selenium - Text not pulling through from Xpath

提问人:Danjo9 提问时间:10/13/2023 最后编辑:Michael MintzDanjo9 更新时间:10/13/2023 访问量:85

问:

我编写了一些VBA代码,以从网页中提取一些统计信息。几乎所有的信息都通过了,但玩家的名字是唯一没有返回的信息。我已经尝试了不同版本的名称(完整、简短、第一个、最后一个),但似乎没有任何效果。该代码与返回的所有其他信息完全相同。我一直在使用 XPath 来访问文本,因为我发现该网站不时更改类名。这是我的代码:

Set ch = New Selenium.ChromeDriver
ch.AddArgument "--headless"
ch.Get "https://www.euroleaguebasketball.net/eurocup/game-center/2023-24/cedevita-olimpija-ljubljana-joventut-badalona/U2023/12/#boxscore"

Set sht = Sheets("Sheet1")
Rw = 1
Base = "//*[@id='main']/div/div/div[2]/div/div[3]/div/div[2]/div/div[1]/div/div[1]/"
For Rw = 1 To 20
    Exists = ch.FindElementsByXPath(Base & "div[1]/div[" & Rw & "]/span").Count
    
    If Exists > 0 Then
    sht.Cells(Rw, 1) = ch.FindElementByXPath(Base & "div[1]/div[" & Rw & "]/span").Text
    sht.Cells(Rw, 2) = ch.FindElementByXPath(Base & "div[1]/div[" & Rw & "]/a/div[1]").Text
    sht.Cells(Rw, 3) = ch.FindElementByXPath(Base & "div[2]/div[1]/div[" & Rw & "]/div/div[1]").Text
    sht.Cells(Rw, 4) = ch.FindElementByXPath(Base & "div[2]/div[1]/div[" & Rw & "]/div/div[2]").Text
    sht.Cells(Rw, 5) = ch.FindElementByXPath(Base & "div[2]/div[2]/div[" & Rw & "]/div/div[1]").Text
    sht.Cells(Rw, 6) = ch.FindElementByXPath(Base & "div[2]/div[2]/div[" & Rw & "]/div/div[2]").Text
    sht.Cells(Rw, 7) = ch.FindElementByXPath(Base & "div[2]/div[3]/div[" & Rw & "]/div/div[1]").Text
    sht.Cells(Rw, 8) = ch.FindElementByXPath(Base & "div[2]/div[3]/div[" & Rw & "]/div/div[2]").Text
    sht.Cells(Rw, 9) = ch.FindElementByXPath(Base & "div[2]/div[4]/div[" & Rw & "]/div/div[1]").Text
    sht.Cells(Rw, 10) = ch.FindElementByXPath(Base & "div[2]/div[4]/div[" & Rw & "]/div/div[2]").Text
    sht.Cells(Rw, 11) = ch.FindElementByXPath(Base & "div[2]/div[5]/div[" & Rw & "]/div/div[1]").Text
    sht.Cells(Rw, 12) = ch.FindElementByXPath(Base & "div[2]/div[5]/div[" & Rw & "]/div/div[2]").Text
    sht.Cells(Rw, 13) = ch.FindElementByXPath(Base & "div[2]/div[5]/div[" & Rw & "]/div/div[3]").Text
    sht.Cells(Rw, 14) = ch.FindElementByXPath(Base & "div[2]/div[6]/div[" & Rw & "]/div/div[1]").Text
    sht.Cells(Rw, 15) = ch.FindElementByXPath(Base & "div[2]/div[6]/div[" & Rw & "]/div/div[2]").Text
    sht.Cells(Rw, 16) = ch.FindElementByXPath(Base & "div[2]/div[6]/div[" & Rw & "]/div/div[3]").Text
    sht.Cells(Rw, 17) = ch.FindElementByXPath(Base & "div[2]/div[7]/div[" & Rw & "]/div/div[1]").Text
    sht.Cells(Rw, 18) = ch.FindElementByXPath(Base & "div[2]/div[7]/div[" & Rw & "]/div/div[2]").Text
    sht.Cells(Rw, 19) = ch.FindElementByXPath(Base & "div[2]/div[8]/div[" & Rw & "]/div/div[1]").Text
    sht.Cells(Rw, 20) = ch.FindElementByXPath(Base & "div[2]/div[8]/div[" & Rw & "]/div/div[2]").Text
    sht.Cells(Rw, 21) = ch.FindElementByXPath(Base & "div[2]/div[9]/div[" & Rw & "]/div/div[1]").Text
    sht.Cells(Rw, 22) = ch.FindElementByXPath(Base & "div[2]/div[9]/div[" & Rw & "]/div/div[2]").Text

    End If
Next Rw

我得到这个:

Excel Screenshot

所以数字正在拉进来(我可以修复格式),但名称只是空白。

Excel VBA 网页抓取 selenium-chromedriver

评论


答:

0赞 Yaroslavm 10/13/2023 #1

首先,不要使用绝对路径,用它读取代码是不可能的,绝对路径很难支持。更改树中存在的一个元素会破坏您的定位器。XPATHDOMXPATH

代替它,使用缩短的“相对”声明。

参考

例如,变量的唯一定位器是Base//div[contains(@class, 'is-active')]//*[contains(@class, 'game-box-scores-table-grouped-tab_tableGrouped_')]

它很容易找到 - 你去你的基本元素并查看它的属性。你看到它有看似独特的类。你搜索类,你会得到 2 个元素。但你只需要 1 个。你看它的父级,你看,你的表的一个父级有类,它指向可见的表。game-box-scores-table-grouped-tab_tableGrouped_'is-active

我们得到了简短而解释性的文章。然后我们寻找玩家的名字。 检查元素,我们看到它具有仅属于名称的唯一类部分。BaseplayerFullName

它的Xpath定位器是//*[contains(@class, 'playerFullName’)]

因此,我们只需要使用此选择器获取元素数组并按索引获取所需的行(在您的情况下)Rw

Base = "//div[contains(@class, 'is-active')]//*[contains(@class, 'game-box-scores-table-grouped-tab_tableGrouped_')]/"
For Rw = 1 To 20
    // your code
    sht.Cells(Rw, yourCell) = ch.FindElements(By.XPath(Base & "/*[contains(@class, 'playerFullName’)]"))(Rw).Text

评论

0赞 Danjo9 10/14/2023
感谢@Yaroslavm对这条路的建议。起初我仍然无法让它工作,但我发现这是因为 playerFullName 是空的,除非窗口最大化,并且因为我添加了无头参数,所以它没有最大化。如果我将参数更改为“start-maximized”,我将返回 playerFullName。使用您的建议来获取其余数据是一个小挑战,因为它们都位于 tableStatCell 中,但我想我已经做到了