问题
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