为什么 运行 交互式与 Python 脚本中的 Selenium 输出不同?

Why is the Selenium output different if run interactively vs in a Python script?

我在 Python 3 中使用 Selenium 来获取使用 JavaScript 的站点的页面源代码。当我 运行 它在 iPython shell 中以交互方式运行时,它会按照我的预期运行。但是,当以非交互方式执行完全相同的脚本时,页面源未完全呈现(未呈现 JavaScript 组件)。这可能是什么原因?我 运行 在完全相同的机器(无头 Linux 服务器)上使用完全相同的代码。

#!/usr/bin/python3

from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.chrome.options import Options

WINDOW_SIZE = "1920,1080"

chrome_options = Options()
chrome_options.add_argument("--headless")
chrome_options.add_argument("--window-size={0}".format(WINDOW_SIZE))
chrome_options.add_argument("--no-sandbox")

service = Service('/usr/local/bin/chromedriver')
driver = webdriver.Chrome(service=service, options=chrome_options)

driver.get("https://www.stakingrewards.com/staking/?page=1&sort=rank_ASC")
src  = driver.page_source

# Check page source length
print(len(src))

# Quit all windows related to the driver instance
driver.quit()

iPython shell 的输出是 220101,这是预期的,而命令行执行脚本 ($ python script.py) 的输出是 38265.因此,当我从命令行调用脚本时,我没有有效地呈现 JavaScript 组件。为什么?!

问题不在于 运行 它以交互方式或作为脚本。

在您的代码中,您实际上并没有给驱动程序任何时间来呈现所有元素,从而导致源代码不完整。恰好 运行 它作为脚本交互比 运行 它快一点,导致页面源长度更大。但是,我能够使用 Waits(大约 650k)获得更大的页面源长度。

Waits 可用于等待所需元素成为 visible/present 等。在您的情况下,我假设它是主要的 table。 下面的给定代码等待 table 可见,然后 returns 页面源。

代码片段-

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

driver.get("https://www.stakingrewards.com/staking/?page=1&sort=rank_ASC")

try:
#waiting for table data to be visible
    delay=20 #20 second delay
    WebDriverWait(driver, delay).until(EC.visibility_of_element_located((By.CLASS_NAME, 'rt-tbody')))
    print(len(driver.page_source))

#raises Exception if element is not visible within delay duration
except TimeoutException:
    print("Timeout!!!")

driver.quit()