Taking a whole page screenshot with Selenium Marionette in Python

你离开我真会死。 提交于 2019-12-28 18:51:19

问题


After the recent Firefox upgrade to version 47 we were forced to install the Marionette extension to keep being able to use selenium webdriver, and in my case also upgrade selenium from 2.52 to 2.53.

I use the python version of selenium webdriver to acquire high resolution images of maps rendered in HTML and JavaScript. previously this worked fine in firefox and the screenshots could be taken of the whole page, far beyond the dimensions of my own screen. However with the recent changes the screenshot is taken only of the area visible on screen. I use the following code:

import time
from selenium import webdriver
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities

caps = DesiredCapabilities.FIREFOX
caps["marionette"] = True

browser = webdriver.Firefox(capabilities=caps)
browser.get(html_file)
time.sleep(15)

browser.save_screenshot(image_name)
browser.quit()

I have already considered: downgrading, stitching together several screenshots or switching to Qgis. However I would prefer a more elegant solution which would allow me to keep using the latest version of firefox and roughly the same methodology. Does anyone know a solution to this? perhaps by tricking selenium in thinking the viewport is larger? or by using another linux supported browser which does allow for the full page screenshot?


回答1:


This is what I use, just stitch it:

#!/usr/bin/python
from selenium import webdriver
from PIL import Image
from cStringIO import StringIO

verbose = 1

browser = webdriver.Firefox()
browser.get('http://stackoverflow.com/questions/37906704/taking-a-whole-page-screenshot-with-selenium-marionette-in-python')

# from here http://stackoverflow.com/questions/1145850/how-to-get-height-of-entire-document-with-javascript
js = 'return Math.max( document.body.scrollHeight, document.body.offsetHeight,  document.documentElement.clientHeight,  document.documentElement.scrollHeight,  document.documentElement.offsetHeight);'

scrollheight = browser.execute_script(js)

if verbose > 0: 
    print scrollheight

slices = []
offset = 0
while offset < scrollheight:
    if verbose > 0: 
        print offset

    browser.execute_script("window.scrollTo(0, %s);" % offset)
    img = Image.open(StringIO(browser.get_screenshot_as_png()))
    offset += img.size[1]
    slices.append(img)

    if verbose > 0:
        browser.get_screenshot_as_file('%s/screen_%s.png' % ('/tmp', offset))
        print scrollheight


screenshot = Image.new('RGB', (slices[0].size[0], scrollheight))
offset = 0
for img in slices:
    screenshot.paste(img, (0, offset))
    offset += img.size[1]

screenshot.save('/tmp/test.png')

code also here: https://gist.github.com/fabtho/13e4a2e7cfbfde671b8fa81bbe9359fb

Problem with scrolling/stich are, that html nodes set to "display: fixed" keep repeating on every shot you do.




回答2:


Got good results with this. It's headless, but for normal mode will be probably the same result.

from selenium import webdriver

firefox_options = webdriver.FirefoxOptions()
firefox_options.set_headless() 

firefox_driver = webdriver.Firefox(executable_path=<path_to_gecko_driver>, firefox_options=firefox_options)
firefox_driver.get(<some_url>)

firefox_elem = firefox_driver.find_element_by_tag_name('html')
firefox_elem.screenshot(<png_screenshot_file_path>)



回答3:


Looks like it can be done like:

from selenium import webdriver

browser = webdriver.PhantomJS()
browser.get('http://stackoverflow.com/questions/37906704/taking-a-whole-page-screenshot-with-selenium-marionette-in-python')
browser.save_screenshot('screen.png')


来源:https://stackoverflow.com/questions/37906704/taking-a-whole-page-screenshot-with-selenium-marionette-in-python

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!