WallpapersCraft.com Downloader
Automate the wallpaper download process from WallpapersCraft.com with php.
There are a lot of websites offering wallpaper images and many of them also offer an API to automatically download them via an application interface. This script demonstrates how to parse the website HTML directly, while offering a simple public class to make image downloads as easy as possible.
The first part of the script sets the private variables. Some of these are specific to the WallpapersCraft.com website, like the categories. It is vital to understand how pages and the cache are being used by this script, in order to make changes and updates. Once the script receives the HTML output from the website, it is parsed for possible pagination results, based on the page limit, the script will request each page separately and add it to the page array. The results as stored by category in the cache, thus subsequent requests return hits from the cache array.
Be warned that our script contains a lot of debug “echo” lines, which are obviously suboptimal and should not be included in a usable script, but they are there to help users learn more about the way the script is working (or not).
wcd.php
- #!/usr/bin/php
- <?php
- /*
- * WallpapersCraft.com Downloader
- */
- Class WCDRecord {
- /* PRIVATE VARIABLES */
- // Debug mode
- private $debug = false;
- // Category URL part
- private $category = "";
- // Resolution URL part
- private $resolution = "";
- // Sort by URL part
- private $sortby = "";
- // List of category names and URL parts
- '3D' => "/3d",
- 'Abstract' => "/abstract",
- 'Animals' => "/animals",
- 'Anime' => "/anime",
- 'Brands' => "/brands",
- 'Cars' => "/cars",
- 'City' => "/city",
- 'Fantasy' => "/fantasy",
- 'Flowers' => "/flowers",
- 'Food' => "/food",
- 'Games' => "/games",
- 'Girls' => "/girls",
- 'Hi-Tech' => "/hi-tech",
- 'Holidays' => "/holidays",
- 'Macro' => "/macro",
- 'Men' => "/men",
- 'Movies' => "/movies",
- 'Music' => "/music",
- 'Nature' => "/nature",
- 'Other' => "/other",
- 'Space' => "/space",
- 'Sport' => "/sport",
- 'Textures' => "/textures",
- 'TV Series' => "/tv-series",
- 'Vector' => "/vector"
- );
- // List of sorting names and URL parts
- 'Ratings' => "",
- 'Downloads' => "/downloads",
- 'Date' => "/date"
- );
- // Main domain URL
- private $mainUrl = 'https://wallpaperscraft.com';
- // User agent for curl calls
- private $userAgent = 'Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Firefox/38.0';
- // Cookie file
- private $cookieFile = '/tmp/wcd-cookie.dat';
- // Temporary file
- private $tmpFile = '/tmp/wcd-tmp.jpg';
- // Referer URL
- private $referer = '';
- // HTML temporary cache (array, each element represents a different page of the same category/resolution/sort combination)
- // Page limit
- private $pageLimit = 20;
- // Page cache data file
- private $cacheFile = '/tmp/.wcd-cache';
- // Page cache
- // Image cache
Below are the private functions of the script. The getHTML() function uses CURL to request HTML pages from the website, the getFile() function uses CURL to request image files directly, the parsePages() function parses the HTML script for possible pagination results, the getPages() function is a wrapper function to download all the available pages based on the initial request of the script and the available cache array, the getImageList() function scans the downloaded pages for possible images to download and the selectRandomImage() function just picks one random image to download.
wcd.php
- /* PRIVATE FUNCTIONS */
- private function getHTML($url) {
- // Cache
- if($this->debug==true) echo "[WCD| Get page from cache ".$url."]\n";
- return $this->pages[$url];
- }
- // Get URL
- if($this->debug==true) echo "[WCD| Get page ".$url."]\n";
- // Initialize curl
- // Set curl options
- // Use a referer if one is available
- if($this->referer!="")
- if($this->debug==true) echo "[WCD| Curl execution...";
- // Execute curl
- if($this->debug==true) echo "OK]\n";
- // Handle curl error
- if($rc===false && $this->debug==true) {
- echo "[WCD| Curl returned error:\n";
- }
- // Close curl connection
- if($rc!==false) {
- // Store URL for future use as a referer
- $this->referer = $url;
- // Store page to cache
- $this->pages[$url] = $rc;
- }
- return $rc;
- }
- private function getFile($url, $dest) {
- // Get URL
- if($this->debug==true) echo "[WCD| Get file ".$url."]\n";
- // File pointer
- // Initialize curl
- // Set curl options
- // Use a referer if one is available
- if($this->referer!="")
- // Curl debug mode (disabled)
- //if($this->debug==true) {
- // curl_setopt($handle, CURLOPT_VERBOSE, true);
- // curl_setopt($handle, CURLOPT_CERTINFO, true);
- //}
- if($this->debug==true) echo "[WCD| Curl execution...";
- // Execute curl
- if($this->debug==true) echo "OK]\n";
- // Handle curl error
- if($rc===false && $this->debug==true) {
- echo "[WCD| Curl returned error:\n";
- }
- // Close curl connection
- // Close file pointer
- return $rc;
- }
- private function parsePages(&$html) {
- // Find start of pages div
- if($pos===false)
- return false;
- // Find end of pages div
- if($pos2===false)
- return false;
- // Extract pages div
- if($pages===false || $pages=="")
- return false;
- // Find last page
- if($pos===false)
- return false;
- // Extract last page
- return false;
- // Cast to integer
- $matches[1] = (int)$matches[1];
- if($this->debug==true) echo "[WCD| Total number of pages: ".$matches[1].", limit set to: ".$this->pageLimit."]\n";
- return $matches[1];
- }
- private function getPages() {
- // Generate complete URL
- $url = $this->mainUrl.$this->category.$this->sortby.$this->resolution;
- if($this->debug==true) echo "[WCD| Page URL: ".$url."]\n";
- // Get 1st page
- $this->html[0] = $this->getHTML($url);
- if($this->html[0]===false) {
- if($this->debug==true) echo "[WCD| Error while downloading HTML page from remote server]\n";
- return false;
- }
- // Parse total number of pages
- $pages = $this->parsePages($this->html[0]);
- if($pages===false) {
- if($this->debug==true) echo "[WCD| Error while parsing for page numbers]\n";
- return false;
- }
- // Generate page array
- for($i=2;$i<=$pages;$i++)
- $pageArray[$i] = $i;
- // Follow page limit, pick a random number of pages
- if($pages > $this->pageLimit)
- // Loop and download all available pages
- foreach($pageArray as $key => $i) {
- // Generate complete URL
- $url = $this->mainUrl.$this->category.$this->sortby.$this->resolution.'/page'.$i;
- if($this->debug==true) echo "[WCD| Page URL: ".$url."]\n";
- // Get page
- $rc = $this->getHTML($url);
- if($rc===false) {
- if($this->debug==true) echo "[WCD| Error while downloading HTML page from remote server]\n";
- return false;
- } else {
- $this->html[] = $rc;
- }
- }
- // Save cache to file
- if($this->debug==true) echo "[WCD| Saving cache file: ".$this->cacheFile."]\n";
- // Store cache
- if($rc===false) {
- if($this->debug==true) echo "[WCD| Error while saving the cache file: ".$this->cacheFile."]\n";
- }
- }
- }
- private function getImageList() {
- foreach($this->html as $h) {
- // Find the start of the wallpapers div
- if($pos===false)
- return false;
- // Find end of the wallpapers div
- if($pos2===false)
- return false;
- // Extract wallpapers div
- if($h===false || $h=="")
- return false;
- // Remove extra domain from URLs
- // Find all images
- return false;
- // Store images to cache
- }
- }
- private function selectRandomImage() {
- // Return random image
- }
At this step, we define the public class structure. The WCDRecord() constructor initializes the cache, the function setCategory() selects the download image category, the setResolution() function sets the resolution requirements of the downloaded image file and the downloadImage() is the actual function that performs all the required actions to download an image file from the website.
The downloadImage() function also sets the downloaded image as the default desktop background, by default for GNOME3/Cinnamon/Mint background and optionally for GNOME2.
wcd.php
- /* PUBLIC FUNCTIONS */
- function WCDRecord($debug=false) {
- $this->debug = $debug;
- // Initialize cache
- if($this->debug==true) echo "[WCD| Loading cache file: ".$this->cacheFile."]\n";
- // Load existing cache
- if($this->debug==true) echo "[WCD| Error while loading the cache file: ".$this->cacheFile."]\n";
- }
- } else {
- if($this->debug==true) echo "[WCD| Set empty cache file: ".$this->cacheFile."]\n";
- // Set empty cache
- // Store empty cache for future use
- if($rc===false) {
- if($this->debug==true) echo "[WCD| Error while saving the cache file: ".$this->cacheFile."]\n";
- }
- }
- }
- function setCategory($category) {
- if($this->debug==true) echo "[WCD| Warning, requested category not recognized]\n";
- $category = 'all';
- }
- if(($category==="" || $category==="all") && $this->resolution==="")
- $this->category = '';
- elseif(($category==="" || $category==="all") && $this->resolution!=="")
- $this->category = '/all';
- else
- $this->category = '/catalog'.$this->categories[$category];
- if($this->debug==true) echo "[WCD| Set category to: ".$this->category."]\n";
- }
- function setResolution($resolution) {
- if($resolution==="") {
- $this->resolution = '';
- if($this->category==="/all")
- $this->category = '';
- } else {
- $this->resolution = '/'.$resolution;
- if($this->category==="")
- $this->category = '/all';
- }
- if($this->debug==true) echo "[WCD| Set resolution to: ".$this->resolution."]\n";
- }
- function setSortBy($sortby) {
- if($this->debug==true) echo "[WCD| Warning, requested sorting not recognized]\n";
- $sortby = 'Ratings';
- }
- if($this->category==="/all")
- $sortby = 'Ratings';
- else
- $this->sortby = $this->sortings[$sortby];
- if($this->debug==true) echo "[WCD| Set sort by to: ".$this->sortby."]\n";
- }
- function downloadImage($destination) {
- // Get pages
- $rc = $this->getPages();
- if($rc===false)
- return false;
- // Get image list
- $rc = $this->getImageList();
- if($rc===false)
- return false;
- // Get random image from image list
- $imagePage = $this->selectRandomImage();
- if($this->debug==true) echo "[WCD| Selected image page: ".$imagePage."]\n";
- // Generate image URL
- $imageUrl = $this->mainUrl.'/image/'.str_replace('/', '_', str_replace('/download/', '', $imagePage)).'.jpg';
- if($this->debug==true) echo "[WCD| Image URL: ".$imageUrl."]\n";
- // Set referer
- $this->referer = $this->mainUrl.$imagePage;
- if($this->debug==true) echo "[WCD| Save image to: ".$destination."]\n";
- // Delete temporary file
- if($this->debug==true) echo "[WCD| Temporary file already exists, deleting]\n";
- }
- // Get file
- $rc = $this->getFile($imageUrl, $this->tmpFile);
- if($rc===false) {
- if($this->debug==true) echo "[WCD| Error while downloading image file from remote server]\n";
- return false;
- }
- // Get file size
- if($size===false || $size==0) {
- if($this->debug==true) echo "[WCD| File size error]\n";
- return false;
- }
- if($this->debug==true) echo "[WCD| Size of downloaded image file: ".$size." bytes]\n";
- if($this->debug==true) echo "[WCD| Mogrify image...";
- // ImageMagick resize and crop
- `/usr/bin/mogrify -quality 100% -filter Lanczos -distort Resize 3440x1440^ -gravity center -extent 3440x1440 "$this->tmpFile"`;
- if($this->debug==true) echo "OK]\n";
- // Move temporary file to destination, override destination if it exists
- if($rc===false) {
- if($this->debug==true) echo "[WCD| Error while moving temporary file to destination]\n";
- return false;
- }
- // Set GNOME2 background
- //`/usr/bin/gconftool-2 -t string -s /desktop/gnome/background/picture_filename "$destination"`;
- // Set GNOME3/Cinnamon/Mint background
- `/usr/bin/gsettings set org.cinnamon.desktop.background picture-uri "file://$destination"`;
- if($this->debug==true) echo "[WCD| Image set as background]\n";
- }
- }
In the last step we demonstrate how to execute the script and call the public functions. Once the WCDRecord() class is instantiated, we download a random image from any category, at a resolution of 3840x2160, by sorting the results by date and saving the final image as background.jpg in the current directory.
wcd.php
- $wcd = new WCDRecord(false);
- $wcd->setCategory("all");
- $wcd->setResolution("3840x2160");
- $wcd->setSortBy("Date");
- $wcd->downloadImage('background.jpg');
So what have we achieved so far? We managed to create a quick parser for a single website, a simple method to poll results from multiple pages and a simple way of modifying the downloaded image via ImageMagick to our required resolution. Finally, we automatically set our modified image as a background wallpaper.
What is missing, is a more abstract way of downloading images from multiple websites, but that is left as an exercise to the reader.
- Posted by Dimitris Dimitropoulos · Nov. 28, 2016