我正在使用 Python 和 Selenium 构建一个网络抓取工具来抓取篮球参考网站,并且需要对返回我正在查找的数据的 Xpath 语句进行一些微调。目前,我需要一些 Xpath 语句来返回除最后一行之外的每一行,即“奖项”行,该行有时包含文本(如果玩家当年赢得了任何类型的奖项),如果没有,则为空白。我的代码工作正常,并且 mostly 确实选择了我需要的内容,但是我尝试过的 Xpath 语句的每个变体要么不返回有效的 Xpath 语句,要么只是为我提供了包括最后一行在内的所有数据,我就是这么做的不需要。这是我的工作代码片段以及 selenium 驱动程序代码,它检索表的每个元素并返回它。
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.common.exceptions import NoSuchElementException, TimeoutException
import pandas as pd
class PlayerPerGameStats():
def __init__(self, player_name):
self.player_name = player_name.lower()
self.options = Options()
#No popup window when called
self.options.add_argument("--headless=new")
#No image loading for performance
self.options.add_experimental_option(
"prefs", {
"profile.managed_default_content_settings.images" : 2,
}
)
self.browser = webdriver.Chrome(options=self.options)
self.url = f"https://www.basketball-reference.com/players/{self.player_name[0]}/{self.player_name}01.html"
self.browser.get(self.url)
#Add wait for page load
WebDriverWait(self.browser, 10).until(
EC.presence_of_element_located((By.ID, 'per_game_stats'))
)
def get_player_row_stats(self) -> list:
try:
table = self.browser.find_element(By.ID, 'per_game_stats')
rows = table.find_elements(By.XPATH, './tbody')
stat_rows = [row.text for row in rows[0].find_elements(By.XPATH, './tr')]
#List split to get each stat as it's own index
player_data = [y for x in stat_rows for y in x.split(' ')]
print(player_data)
return player_data
except Exception as e:
print(f"Error extracting row stats: {e}")
return None
#To run it
stats = PlayerPerGameStats("lillada")
stats()
这是我正在使用的 DOM 片段。
我尝试过的一些 xpath 变体包括:
stat_rows = [row.text for row in rows[0].find_elements(By.XPATH, './tr[position() < last()]')]
stat_rows = [row.text for row in rows[0].find_elements(By.XPATH, './tr[not(contains(@data-stat, 'awards'))]')]
然而,这些还不够,而是返回上述每个行或根本不返回任何内容。
感谢您花时间阅读本文。如果需要任何其他信息或代码,我非常乐意提供 - 这个问题已经困扰我好几个星期了,我只是想弄清楚如何解决它。
最简单的解决方案就是简单
stat_rows = [row.text for row in rows[0].find_elements(By.XPATH, './tr')][:-1]
我不知道 xpath,但使用 css 选择器你可以做到
stat_rows = [row.text for row in rows[0].find_elements(By.CSS_SELECTOR, 'tr td:not(:last-of-type)')]