计算某些 class 的实例数并通过 Selenium 获取值

counting number of instances of certain class and acquiring values via Selenium

我正在尝试从 this website 抓取数据。

更具体地说,我希望我的脚本计算 table 中的行数并从每一行中提取出席人数(请参阅下面的图片。)

检查该网站,我在第一行(12 月 1 日)看到以下日期:

<td ng-repeat="(k,h) in sec.headers track by $index" class="date ng-scope" data-high="false" data-hidden="false" 
ng-style="{'text-align':h.properties.align}" ng-bind-html="vals | getColData:[k]:language:seasonId" 
compile-table-col="" style="text-align: left;"><span>Dec. 1</span></td>

然后,我在第一行 (872) 中看到了人群计数代码块

<td ng-repeat="(k,h) in sec.headers track by $index" class="attendance ng-scope" data-high="false" 
data-hidden="false" ng-style="{'text-align':h.properties.align}" ng-bind-html="vals | getColData:[k]:language:seasonId" 
compile-table-col="" style="text-align: right;"><span>872</span></td>

我试过 driver.find_elements_by_class_name 的多个版本,例如

elements = driver.find_elements_by_class_name("date ng-scope") 

driver.find_elements_by_xpath("//td[@class='date ng-scope']")))

不幸的是,其中 none 个有效。

有人能给我指出正确的方向吗?如果有人可以提供有关如何通过计算 'date ng-scope' 的实例数并提取相应的人群计数来正确计算行数的建议。

因为它是一个 table,所以很容易实现,因为您需要做的就是不断地将 table 的值递增 1。我就是这样做的:

from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from time import sleep, strftime

url = "https://www.ushl.com/view#/schedule/24/67/12/home?league=1&gametype=-1"

webdriver = webdriver.Chrome()
webdriver.get(url)

x = 0
i = 2

while x == 0:
    try:
        date = webdriver.find_element_by_xpath(f"/html/body/div[5]/div[1]/div[4]/div[2]/div[1]/div/div[3]/div/div/div/div/div/div/ng-view/div[2]/div[3]/div[1]/table/tbody/tr[{i}]/td[1]/span").text
        attendance = webdriver.find_elements_by_xpath(f"/html/body/div[5]/div[1]/div[4]/div[2]/div[1]/div/div[3]/div/div/div/div/div/div/ng-view/div[2]/div[3]/div[1]/table/tbody/tr[{i}]/td[8]/span")[0].text

        print(f"Attendance Of {attendance} On Date {date}")
        i += 1
    except:
        x = 1
        break

让我解释一下:

第 1 - 3 行导入必要的模块,例如 selenium。

第 4 行将 url 设置为字符串。

第 5 行将 webdriver 定义为 Chrome。

第 6 行使用 Chrome 打开我们之前定义的 url。

第 7 行将 x 定义为 0。对于后面的 while 循环,我们需要 x 为 0。

第 8 行将 i 定义为 2,我们稍后 table 需要它。

第 9 行启动一个 while 循环,只要 x 为 0(我们之前将其设置为 0),该循环就会 运行。

第 10 行启动一个 try 命令。您稍后会明白我们为什么需要它。

第 11 行将日期设置为 xpath 变量的文本。我以前用过html,所以我大致知道table系统是如何工作的。 tr 代表 table 行。第一个日期,12 月 1 日是 table 行 2。我们之前将 i 设置为 2,因此我们可以使用 tr[{i}], 来表示 2.

第 12 行做完全相同的事情,但对于出勤,仍然使用 i,因为它是 table。我在末尾添加了 [0],因为出勤的 xpath 是一个列表。尽管我很确定没有列表,但 selenium 仍然这么认为,所以我决定使用 [0] 来获取列表的第一个元素。没有秒或第三个元素,因此 [1] 或 [2] 将不起作用。

第13行打印用户信息。 第 14 行将 i 递增 1,因为在下一个循环中,我们需要访问第 3 table 行,因此 i += 1 将 i 设置为 3.

我们继续 运行 直到没有更多的 table 行。发生这种情况时,我们使用第 15 行的 try 命令来打破 while 循环。

桌子很有趣。我发现最好从外面钻进去,而不是先直接进入你想要的元素。比如行数。

driver.findElements("//div[contains(@class,'table-container')]//tr") 

将 return 一个元素列表,获取该列表的大小可以得到行数(这包括 header 行,所以如果你想要实际的游戏数减去 1 ).翻译后的 xpath 表达式是“找到任何 div 元素,其中 class 名称包含字符串“table-container”,并且在该元素的下游,任何 tr 元素

可以使用此 xpath 找到出勤字段:

//div[contains(@class,'table-container')]//tr[2]/td[contains(@class,'attendance')]/span

其中 tr[2] 表示第二行。以编程方式,使“[2]”成为一个变量并将循环索引替换为 2 并遍历行计数。

使用WebDriverWait()并等待visibility_of_all_elements_located()并使用下面的css selector确定行数然后迭代并找到各自的 .

driver.get("https://www.ushl.com/view#/schedule/24/67/12/home?league=1&gametype=-1")
totalnoofrows=WebDriverWait(driver, 10).until(EC.visibility_of_all_elements_located((By.CSS_SELECTOR, ".resp >.ht-table >tbody >tr")))
for row in totalnoofrows[1:]:
    print("Date :" + row.find_element_by_xpath("./td[1]").text)
    print("Crowd :" + row.find_element_by_xpath("./td[8]").text)
    print("==============================================")

您需要导入以下库。

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

控制台输出:

Date :Dec. 1
Crowd :872
==============================================
Date :Dec. 14
Crowd :816
==============================================
Date :Dec. 15
Crowd :1065
==============================================
Date :Dec. 16
Crowd :497
=============================================