Website screenshots

Viewed 345255

Is there any way of taking a screenshot of a website in PHP, then saving it to a file?

18 Answers

LAST EDIT: after 7 years I'm still getting upvotes for this answer, but I guess this one is now much more accurate.


Sure you can, but you'll need to render the page with something. If you really want to only use php, I suggest you HTMLTOPS, which renders the page and outputs it in a ps file (ghostscript), then, convert it in a .jpg, .png, .pdf.. can be little slower with complex pages (and don't support all the CSS).

Else, you can use wkhtmltopdf to output a html page in pdf, jpg, whatever.. Accept CSS2.0, use the webkit (safari's wrapper) to render the page.. so should be fine. You have to install it on your server, as well..

UPDATE Now, with new HTML5 and JS feature, is also possible to render the page into a canvas object using JavaScript. Here a nice library to do that: Html2Canvas and here is an implementation by the same author to get a feedback like G+. Once you have rendered the dom into the canvas, you can then send to the server via ajax and save it as a jpg.

EDIT: You can use the imagemagick tool for transforming pdf to png. My version of wkhtmltopdf does not support images. E.g. convert html.pdf -append html.png.

EDIT: This small shell script gives a simple / but working usage example on linux with php5-cli and the tools mentioned above.

EDIT: i noticed now that the wkhtmltopdf team is working on another project: wkhtmltoimage, that gives you the jpg directly

Since PHP 5.2.2 it is possible, to capture a website with PHP solely!

imagegrabscreen — Captures the whole screen

<?php
$img = imagegrabscreen();
imagepng($img, 'screenshot.png');
?>

imagegrabwindow - Grabs a window or its client area using a windows handle (HWND property in COM instance)

<?php
$Browser = new COM('InternetExplorer.Application');
$Browserhandle = $Browser->HWND;
$Browser->Visible = true;
$Browser->Fullscreen = true;
$Browser->Navigate('http://www.stackoverflow.com');

while($Browser->Busy){
  com_message_pump(4000);
}

$img = imagegrabwindow($Browserhandle, 0);
$Browser->Quit();
imagepng($img, 'screenshot.png');
?>

Edit: Note, these functions are available on Windows systems ONLY!

There is a lot of options and they all have their pros and cons. Here is list of options ordered by implementation difficulty.

Option 1: Use an API (the easiest)

Pros

  • Execute Javascript
  • Near perfect rendering
  • Fast when caching options are correctly used
  • Scale is handled by the APIs
  • Precise timing, viewport, ...
  • Most of the time they offer a free plan

Cons

  • Not free if you plan to use them a lot

Option 2: Use one of the many available libraries

Pros

  • Conversion is quite fast most of the time

Cons

  • Bad rendering
  • Does not execute javascript
  • No support for recent web features (FlexBox, Advanced Selectors, Webfonts, Box Sizing, Media Queries, HTML5 tags...)
  • Sometimes not so easy to install
  • Complicated to scale

Option 3: Use PhantomJs and maybe a wrapper library

Pros

  • Execute Javascript
  • Quite fast

Cons

  • Bad rendering
  • PhantomJs has been deprecated and is not maintained anymore.
  • No support for recent web features (FlexBox, Advanced Selectors, Webfonts, Box Sizing, Media Queries, HTML5 tags...)
  • Complicated to scale
  • Not so easy to make it work if there is images to be loaded ...

Option 4: Use Chrome Headless and maybe a wrapper library

Pros

  • Execute Javascript
  • Near perfect rendering

Cons

  • Not so easy to have exactly the wanted result regarding:
    • page load timing
    • proxy integration
    • auto scrolling
    • ...
  • Complicated to scale
  • Quite slow and even slower if the html contains external links

Disclaimer: I'm the founder of ApiFlash. I did my best to provide an honest and useful answer.

I used bluga. The api allows you to take 100 snapshots a month without paying, but sometimes it uses more than 1 credit for a single page. I just finished upgrading a drupal module, Bluga WebThumbs to drupal 7 which allows you to print a thumbnail in a template or input filter.

The main advantage to using this api is that it allows you to specify browser dimensions in case you use adaptive css, so I am using it to get renderings for the mobile and tablet layout as well as the regular one.

There are api clients for the following languages:

PHP, Python, Ruby, Java, .Net C#, Perl and Bash (the shell script looks like it requires perl)

There are some ways in which you can achieve this in PHP, but realistically it's better to delegate this to a non-PHP based API which you can build yourself, or you can pay for. Many people have already listed screenshot APIs in the answers, and you can use any of those to achieve this. My own screenshot API is extremely well tested and covers many rendering cases that most APIs don't cover, but for most people, this is overkill, honestly.

My recommendation is to build your own API using Puppeteer, which is the canonical solution nowadays to build screenshot solutions. My service is built on top of Puppeteer and it really works well for most basic use cases.

You can build a serverless Puppeteer solution on AWS or GCP using something like https://www.npmjs.com/package/chrome-aws-lambda, which is an excellent serverless package for Puppeteer that comes pre-loaded with Chromium.

Not directly. Software such as Selenium have features like this and can be controlled by PHP but have other dependencys (such as running their java-based server on the computer with the browser you want to screenshot)

I've found this to be the best and easiest tool around: ScreenShotMachine. It's a paid service, but you get 100 free screenshots and you can buy another 2,000 for (about) $20, so it's a pretty good deal. It has a very simple usage, you just use a URL, so I wrote this little script to save a file based on it:

<?php
  $url = file_get_contents("http://api.screenshotmachine.com/?key={mykey}&url=https://stackoverflow.com&size=X");

  $file = fopen("snapshots/stack.jpg", "w+");
  fwrite($file, $url);
  fclose($file);
  die("saved file!");
?>

They have a very good documentation here, so you should definitely take a look.

Related