How to download an image with Python 3/Selenium if the URL begins with "blob:"? How to download an image with Python 3/Selenium if the URL begins with "blob:"? selenium selenium

How to download an image with Python 3/Selenium if the URL begins with "blob:"?


A blob is a filelike object of raw data stored by the browser.

You can see them at chrome://blob-internals/

It's possible to get the content of a blob with Selenium with a script injection. However, you'll have to comply to the cross origin policy by running the script on the page/domain that created the blob:

def get_file_content_chrome(driver, uri):  result = driver.execute_async_script("""    var uri = arguments[0];    var callback = arguments[1];    var toBase64 = function(buffer){for(var r,n=new Uint8Array(buffer),t=n.length,a=new Uint8Array(4*Math.ceil(t/3)),i=new Uint8Array(64),o=0,c=0;64>c;++c)i[c]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".charCodeAt(c);for(c=0;t-t%3>c;c+=3,o+=4)r=n[c]<<16|n[c+1]<<8|n[c+2],a[o]=i[r>>18],a[o+1]=i[r>>12&63],a[o+2]=i[r>>6&63],a[o+3]=i[63&r];return t%3===1?(r=n[t-1],a[o]=i[r>>2],a[o+1]=i[r<<4&63],a[o+2]=61,a[o+3]=61):t%3===2&&(r=(n[t-2]<<8)+n[t-1],a[o]=i[r>>10],a[o+1]=i[r>>4&63],a[o+2]=i[r<<2&63],a[o+3]=61),new TextDecoder("ascii").decode(a)};    var xhr = new XMLHttpRequest();    xhr.responseType = 'arraybuffer';    xhr.onload = function(){ callback(toBase64(xhr.response)) };    xhr.onerror = function(){ callback(xhr.status) };    xhr.open('GET', uri);    xhr.send();    """, uri)  if type(result) == int :    raise Exception("Request failed with status %s" % result)  return base64.b64decode(result)bytes = get_file_content_chrome(driver, "blob:https://developer.mozilla.org/7f9557f4-d8c8-4353-9752-5a49e85058f5")


Blobs are not actual files to be remotely retrieved by a URI. Instead, they are programatically generated psuedo-URLs which are mapped to binary data in order to give the browser something to reference. I.e. there is no attribute of <img> to provide raw data so you instead create a blob address to map that data to the standard src attribute.

From the MDN page linked above:

The only way to read content from a Blob is to use a FileReader. The following code reads the content of a Blob as a typed array.

var reader = new FileReader();reader.addEventListener("loadend", function() {   // reader.result contains the contents of blob as a typed array});reader.readAsArrayBuffer(blob);


For people who are trying to do the same in node and selenium, please refer below.

var script = function (blobUrl) {    console.log(arguments);    var uri = arguments[0];    var callback = arguments[arguments.length - 1];    var toBase64 = function(buffer) {        for(var r,n=new Uint8Array(buffer),t=n.length,a=new Uint8Array(4*Math.ceil(t/3)),i=new Uint8Array(64),o=0,c=0;64>c;++c)            i[c]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".charCodeAt(c);for(c=0;t-t%3>c;c+=3,o+=4)r=n[c]<<16|n[c+1]<<8|n[c+2],a[o]=i[r>>18],a[o+1]=i[r>>12&63],a[o+2]=i[r>>6&63],a[o+3]=i[63&r];return t%3===1?(r=n[t-1],a[o]=i[r>>2],a[o+1]=i[r<<4&63],a[o+2]=61,a[o+3]=61):t%3===2&&(r=(n[t-2]<<8)+n[t-1],a[o]=i[r>>10],a[o+1]=i[r>>4&63],a[o+2]=i[r<<2&63],a[o+3]=61),new TextDecoder("ascii").decode(a)    };    var xhr = new XMLHttpRequest();    xhr.responseType = 'arraybuffer';    xhr.onload = function(){ callback(toBase64(xhr.response)) };    xhr.onerror = function(){ callback(xhr.status) };    xhr.open('GET', uri);    xhr.send();}driver.executeAsyncScript(script, imgEleSrc).then((result) => {    console.log(result);})

For detailed explanation, please refer below linkhttps://medium.com/@anoop.goudar/how-to-get-data-from-blob-url-to-node-js-server-using-selenium-88b1ad57e36d