Just thoughts

Friday, November 26, 2010

Google Chrome with Xvfb (Headless Server)

Because I'm so damn bored, I tried to set up a box to take screenshots of webpages. This is usually fairly easy to do with khtml2png or with PyQt, but to be honest I haven't heard about a Chrome based screenshot generator. Why Google Chrome? Well, it has libgcflashplayer.so (like... Flash player, anyone?) by default so you don't have to hack your way through pixmaps and get a headache thanks to the flood of segfaults.

The issue is, that Google Chrome doesn't support natively "headless mode" and is very likely that we hit a nice concrete wall fairly fast after we install it and attempt to capture a screenshot with an external program like ImageMagick. But here comes in the picture the X virtual frame buffer, aka. Xvfb.

By now, thanks to all these weird names I used, I hope everyone thinks that it's very hard to persuade Google Chrome to run in a headless environment; it's not.
I grabbed an Ubuntu EC2 micro instance from Amazon (~$15 per month?), ran a few package installs and there you go, had the screenshot generator:

root@localhost: ~# apt-get install xvfb imagemagick
root@localhost: ~# apt-get install google-chrome

For the latter you may need to "force" things, but aptitude will tell you what to do, so I won't.

And kinda that was all you needed, because apt-get will find the dependencies and will install them for you. Now to get a screenshot of a webpage:

root@localhost: ~# xvfb-run --server-args='-screen 0, 1024x768x24' \
google-chrome -start-maximized http://www.example.com \
> & /dev/null &
root@localhost: ~# DISPLAY=:99 import -window root myimage.png

And that's it. There are still some problems, but in general it works neatly. There were two errors I encountered, first being Chrome's inability to create the 'Local State' file in ~/.config/google-chrome/. To fix this I ran [ touch 'Local State' ]. It fixed the issue; if it doesn't for you, find this file on your local system and paste the contents of it into the server's 'Local State' file.
The second issue happened sporadically when I tried to capture a webpage which contained Flash. A segmentation fault occurred which crashed to death the frame buffer. I didn't fix this issue (yet) because, one, it happens rarely, two, even if it happens, running again xvfb-run sets the frame buffer up correctly and I can use import to capture the contents of the root window in the specified display.

And finally, flash content is client side, that is it has to be downloaded before we get something. I say this because if I didn't let Chrome to run the flash for a few seconds, I got an empty container on the screenshot in place of Flash content. To 'fix' this, I let Chrome to run for about 5 seconds, and only then captured the image.

Hope this helps someone :)


Blogger Drew LeSueur said...

apt-get install google-chrome

That didn't work for me.

December 21, 2010 at 9:24 PM  

Post a Comment

Subscribe to Post Comments [Atom]

<< Home