Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Download multiple images at once with Javascript

I'm attempting to download multiple images at once using javascript in a chrome extension. I'd like to do this by firing clicks on each of the images (each wrapped in an href tag with a download attribute, and the class "clickit"). The idea is to loop through each href with the clickit class and fire a mouse click, thus downloading the image.

The following code downloads only the first of n = 25 images, but is called 25 times (console logs "got here" that many times).

var evt = document.createEvent("MouseEvents");

evt.initMouseEvent("click", true, true, window,
        0, 0, 0, 0, 0, false, false, false, false, 0, null);

[].forEach.call( document.getElementsByClassName("clickit"), function(elem){
  console.log("got here");
  elem.dispatchEvent(evt);
});

I've tried an alternate method, but this code almost immediately crashes chrome (throwing KERN_PROTECTION_FAILURE's in the logs):

for (var i = 0; i < document.getElementsByClassName("clickit").length; i++){  
    var clickEvent = document.createEvent("MouseEvents");
    clickEvent.initMouseEvent("click", true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null); 
    document.getElementsByClassName("clickit")[i].dispatchEvent(clickEvent);
}

In both cases, I have a feeling that I'm using the dispatchEvent() function incorrectly, but I cannot put my finger on it. In the first case, the retrieval of a single image properly is encouraging. I have a feeling I'm falling into bad memory access territory with the second case.

Any ideas?

like image 742
pheven Avatar asked Nov 07 '13 07:11

pheven


2 Answers

I don't know what the problem with your code might be (maybe the fact that document.createEvent() has been deprecated), but I was able to donwload some 90 imgs without chrome complaining about it at all (it may ask you once if you allow the webpage to download multiple images, but that's it).
Sample code:

/* Download an img */
function download(img) {
    var link = document.createElement("a");
    link.href = img.src;
    link.download = true;
    link.style.display = "none";
    var evt = new MouseEvent("click", {
        "view": window,
        "bubbles": true,
        "cancelable": true
    });

    document.body.appendChild(link);
    link.dispatchEvent(evt);
    document.body.removeChild(link);
    console.log("Downloading...");
}

/* Download all images in 'imgs'. 
 * Optionaly filter them by extension (e.g. "jpg") and/or 
 * download the 'limit' first only  */
function downloadAll(imgs, ext, limit) {
    /* If specified, filter images by extension */
    if (ext) {
        ext = "." + ext;
        imgs = [].slice.call(imgs).filter(function(img) {
            var src = img.src;
            return (src && (src.indexOf(ext, src.length - ext.length) !== -1));
        });
    }

    /* Determine the number of images to download */
    limit = (limit && (0 <= limit) && (limit <= imgs.length))
            ? limit : imgs.length;

    /* (Try to) download the images */
    for (var i = 0; i < limit; i++) {
        var img = imgs[i];
        console.log("IMG: " + img.src + " (", img, ")");
        download(img);
    }
}

As a demonstration, you can go to this FreeImages.co.uk Gallery, open the console and paste the above code, along with the following:

/* Callback for button's "click" event */
function doit() {
    var imgs = document.querySelectorAll("img");
    downloadAll(imgs, "jpg", -1);
}

/* Create and add a "download" button on the top, left corner */
function addDownloadBtn() {
    var btn = document.createElement("button");
    btn.innerText = "Download all images";
    btn.addEventListener("click", doit);
    btn.style.position = "fixed";
    btn.style.top = btn.style.left = "0px";
    document.body.appendChild(btn);
}
addDownloadBtn();

Then, by clicking the button that appears on the top, left, you'll get yourself a whole bunch of images :)
(NOTE: Your download folder will get filled with 90 images. Modify the "limit" parameter of downloadAll() to limit them if you wish.)

like image 177
gkalpak Avatar answered Sep 22 '22 15:09

gkalpak


You don't need a chrome extension you could runt this in console or make a bookmarklet:

images=document.querySelectorAll("img"); for (i of images) { var a = document.createElement('a'); a.href = i.src; console.log(i); a.download = i.src; document.body.appendChild(a); a.click(); document.body.removeChild(a);}

same thing beautified for reading:

images = document.querySelectorAll("img");
for (i of images) {
    var a = document.createElement('a');
    a.href = i.src;
    console.log(i);
    a.download = i.src;
    document.body.appendChild(a);
    a.click();
    document.body.removeChild(a);
}
like image 23
Eduard Florinescu Avatar answered Sep 20 '22 15:09

Eduard Florinescu