for*_*ice 10 python selenium window-handles webpage-screenshot jupyter-notebook
我将 Selenium 与 Python 结合使用(在 Jupyter 笔记本中)。我打开了许多选项卡,比如说 5 个选项卡(所有元素都已完成加载),我想循环浏览它们并执行两件事:
(在下面的代码中,我重点关注屏幕截图要求,但也非常想知道如何将其另存为 PDF)
此代码允许循环浏览选项卡:
numTabs = len(driver.window_handles)
for x in range(numTabs):
driver.switch_to.window(driver.window_handles[x])
time.sleep(0.5)
Run Code Online (Sandbox Code Playgroud)
但是,如果我尝试添加driver.save_screenshot()
如下所示的调用,代码似乎在拍摄第一个屏幕截图后停止。具体来说,为第一个选项卡(索引为 0)创建“0.png”,并切换到下一个选项卡(索引为 1),但停止进一步处理。它甚至不会循环到下一个选项卡。
numTabs = len(driver.window_handles)
for x in range(numTabs):
driver.switch_to.window(driver.window_handles[x])
driver.save_screenshot(str(x) + '.png') #screenshot call
time.sleep(0.5)
Run Code Online (Sandbox Code Playgroud)
Edit1:
我修改了代码,如下所示,开始从 中截取屏幕截图,window_handles[1]
因为[0]
我实际上并不需要 中的屏幕截图[0]
,但现在甚至没有生成一个屏幕截图。因此,save_screenshot()
即使在初次通话后,该通话似乎也不起作用switch_to.window()
。
tabs = driver.window_handles
for t in range(1, len(tabs)):
print("Processing tab " + tabs[t])
driver.switch_to.window(tabs[t])
driver.save_screenshot(str(t) + '.png') #screenshot call, but the code hangs. No screenshot taking, no further cycling through tabs.
Run Code Online (Sandbox Code Playgroud)
Edit2:
我发现了为什么我的代码“挂起”,无论我使用哪种打印到 PDF 或截取屏幕截图的方法。我之前提到过,新选项卡是通过单击主页上的按钮打开的,但经过仔细检查,我现在看到新选项卡的内容是使用document. write()
. 有一些 ajax 代码可以检索waybillHTML内容,然后使用以下命令将其写入新窗口document.write(waybillHTML)
有关更多上下文,这是一个订单系统,其主页包含订单列表,每个订单旁边有一个按钮,用于打开一个带有运单的新选项卡。重要的是,运单实际上是document. write()
通过单击按钮触发生成的。我注意到在新选项卡中右键单击时“查看页面源代码”选项呈灰色。当我用来switch_to.window()
切换到这些选项卡之一时,会在 300 秒(我想是秒)后Page.printToPDF
超时。
---------------------------------------------------------------------------
TimeoutException Traceback (most recent call last)
<ipython-input-5-d2f601d387b4> in <module>
14 driver.switch_to.window(handles[x])
15 time.sleep(2)
---> 16 data = driver.execute_cdp_cmd("Page.printToPDF", printParams)
17 with open(str(x) + '.pdf', 'wb') as file:
18 file.write(base64.b64decode(data['data']))
...
TimeoutException: Message: timeout: Timed out receiving a message from renderer: 300.000
(Session info: headless chrome=96.0.4664.110)
Run Code Online (Sandbox Code Playgroud)
所以我的精致问题应该是如何Page.printToPDF
在新窗口(使用动态生成document. write()
)中打印页面而不超时?
我尝试的一种方法是这样做:
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
caps = DesiredCapabilities().CHROME
caps["pageLoadStrategy"] = "none"
driver = webdriver.Chrome(options=chrome_options, desired_capabilities=caps)
Run Code Online (Sandbox Code Playgroud)
参考:这个问题
但问题是这太“激进”,并且阻止代码登录到订购系统并进行必要的导航和过滤,以使浏览器到达我获得带有运单生成按钮的订单列表页面(即原始在这个问题中设置)。
Edit3: 此时,我尝试了一些简单的方法,例如获取页面源代码
try:
pageSrc = driver.find_element(By.XPATH, "//*").get_attribute("outerHTML")
print(pageSrc)
Run Code Online (Sandbox Code Playgroud)
动态生成的选项卡(在它们完成渲染很久之后,我可以在屏幕上看到内容(在调试的这个阶段不使用无头)),甚至这本身也会抛出 TimeoutException,所以我不认为这是一个等待内容加载的问题。不知何故,驱动程序无法看到内容。这些页面的生成方式可能有些特殊 - 我不知道。我确信答案中建议的用于截取屏幕截图和保存 PDF 的所有方法对于其他正常窗口来说都很好。在 Chrome 中,该View page source
内容仍然呈灰色,但我可以使用Inspect
.
Edit4: 使用Chrome的检查功能,动态生成页面的页面源具有以下HTML结构:
奇怪的是,即使我能够检查内容,“查看页面源代码”仍然呈灰色:
Edit5:
终于弄清楚了。当我单击生成新选项卡的按钮时,网站将进行 ajax 调用来获取新页面的 HTML 内容,并将document.write
其发送到新选项卡。我想这超出了硒处理的范围。相反,我导入了selenium-wire,用于driver.wait_for_request
拦截 ajax 调用,解析包含新选项卡的 HTML 代码的响应,并将清理后的 HTML 转储到新文件中。从那时起,可以使用其他人已经建议的多种方法轻松处理 PDF 的生成。
由于您的用例是使用 Chrome 内置的另存为 PDF 功能将每个打印为 PDF或拍摄屏幕截图,因此您可能希望一一打开相邻选项卡中的链接并拍摄屏幕截图,而不是同时打开所有附加链接使用以下定位器策略的屏幕截图:
代码块:
num_tabs_to_open = len(elements_href)
windows_before = driver.current_window_handle
# open the links in the adjascent tab one by one to take screenshot
for href in elements_href:
i = 0
driver.execute_script("window.open('" + href +"');")
windows_after = driver.window_handles
new_window = [x for x in windows_after if x != windows_before][0]
driver.switch_to.window(new_window)
driver.save_screenshot(f"image_{str(i)}.png")
driver.close()
driver.switch_to.window(windows_before)
i = i+1
Run Code Online (Sandbox Code Playgroud)
您可以在以下位置找到相关的详细讨论:
归档时间: |
|
查看次数: |
2362 次 |
最近记录: |