用 Selenium 刮一张桌子并打印它

Posted

技术标签:

【中文标题】用 Selenium 刮一张桌子并打印它【英文标题】:Scraping a table with Selenium and printing it 【发布时间】:2021-11-19 16:04:42 【问题描述】:

我想从网站上抓取所有表格。需要自动化才能到达桌子,因此您可能会考虑这一点。我的研究尝试如下:

from selenium.webdriver import Firefox
from selenium.webdriver.common.by import By
from selenium.webdriver.common.action_chains import ActionChains
import time

driver = Firefox(executable_path='/Users/.../PycharmProjects/Sportwinner/geckodriver')
driver.get("https://bskv.sportwinner.de/")
element = driver.find_element(By.ID, "id-button-einstellungen")
actions = ActionChains(driver)
actions.move_to_element(element).perform()
driver.find_element(By.ID, "id-button-einstellungen").click()
element = driver.find_element(By.CSS_SELECTOR, "body")
actions = ActionChains(driver)
actions.move_to_element(element).perform()
driver.find_element(By.ID, "id-klub-name").click()
driver.find_element(By.ID, "id-klub-name").send_keys("Dreieck Schweinfurt")
driver.find_element(By.ID, "id-button-einstellungen-option-ok").click()
time.sleep(1)
driver.find_element(By.ID, "id-dropdown-liga").click()
driver.find_element(By.LINK_TEXT, "Letzte Spielwoche").click()

tableContent = driver.find_elements_by_css_selector("id-table-spiel tr")
for row in tableContent:
    print(row.text)

自从我几个小时前才听说 Selenium 以来,我完全是个菜鸟。我不知道这是否有效,因为我没有看到任何输出。有没有人可以帮助我进行尝试(我想这不正确)以及我怎么可能看到结果?我正在使用 PyCharm 进行编译。

【问题讨论】:

如何到达餐桌? 自动化在我的帖子中给出。但是您可以手动访问bskv.sportwinner.de 并在下拉菜单“Eine Liga auswählen”中选择“Letzte Spielwoche”来查看表格(我的自动化更具体,但我认为所有表格都相同) 请看下面我的回答。 【参考方案1】:

执行速度如此之快,以至于无法从表中提取详细信息。

您需要申请Implicit waitExplicit waits 以便表格数据显示并能够提取详细信息。

# Imports Required
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait

...
driver = webdriver.Chrome(executable_path="chromedriver.exe") # Have tried in Chrome
driver.implicitly_wait(20)

# Or apply Explicit wait like below.
wait = WebDriverWait(driver,30)
wait.until(EC.presence_of_element_located((By.XPATH,"//table[@id='id-table-spiel']//tbody/tr")))

tableContent = driver.find_elements_by_xpath("//table[@id='id-table-spiel']//tbody/tr//div")
for row in tableContent:
    print(row.get_attribute("innerText")) # row.text works too.

你可以这样试试:

tableContent = driver.find_elements_by_xpath("//table[@id='id-table-spiel']//tbody/tr//a")

for i in range(len(tableContent)):
    tableContent[i].click() # Clicks on the "+" icon
    innerrows = driver.find_elements_by_xpath("//tr[@class='detail-view'][]//tr".format(i+1)) #Find the rows inside the 1st and 2nd row.
    for inrow in innerrows:
        elemnets = inrow.find_elements_by_xpath(".//div") # Data are in "div" tags
        data = [] #Collect each row in a list
        for j in elemnets:
            data.append(j.text)
        print(data)
['', '', '1', '', '2', '', '3', '', '4', '', 'Kegel', '', 'SP', '', 'MP', '', '', '', 'MP', '', 'SP', '', 'Kegel', '', '4', '', '3', '', '2', '', '1', '', '', '']
['Krug, Tobias', '141', '141', '136', '86', '141', '152', '124', '131', 'Brandl, Gerald']
['Keller, Ralf', '148', '135', '139', '130', '140', '111', '154', '145', 'Haschke, Jens']

【讨论】:

感谢您的回答。我认为“time.sleep(1)”可以解决这个问题,但正如我所说,我是初学者。您的解决方案的问题是,我需要扩展的表格内容,而不仅仅是内部文本(?)。你知道怎么做吗? @vinceling - 更新了相同的答案。 它对你有用吗?对我来说,输出与以前相同。我猜点击 + 的自动化似乎不起作用 - 至少表格没有扩展 @vinceling - 不,代码点击了“+”并提取了所有细节。请参阅上面的示例输出。 是的,那是我的错,我替换了以前的 tableContent 部分,而不是之后添加新的部分。谢谢我的兄弟,你帮了我很多!【参考方案2】:

到达所需页面后,执行Letzte Spielwoche" in the drop down menu "Eine Liga auswählen" to see the tables

您可以使用此代码

wait = WebDriverWait(driver, 30)
table = wait.until(EC.visibility_of_element_located((By.ID, "id-table-spiel")))
size_of_table = driver.find_elements(By.XPATH, "//table[@id='id-table-spiel']//descendant::tr")
j = 1
for i in range(len(size_of_table)):
    element = driver.find_elements(By.XPATH, f"(//table[@id='id-table-spiel']//descendant::tr)[j]")
    driver.execute_script("arguments[0].scrollIntoView(true);", element)
    print(element.get_attribute('innerText'))
    j = j + 1

进口:

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

【讨论】:

感谢您的帮助,但对我来说到目前为止还没有工作。错误状态: driver.execute_script("arguments[0].scrollIntoView(true);", element)

以上是关于用 Selenium 刮一张桌子并打印它的主要内容,如果未能解决你的问题,请参考以下文章

selenium用jquery改变元素属性

selenium学习笔记 搭建环境

美丽的汤:“ResultSet”对象没有“find_all”属性?

python+Selenium第一个脚本

下载及安装selenium IDE

Laravel Eloquent - 一张桌子的多个模型