-
-
Save florentbr/349b1ab024ca9f3de56e6bf8af2ac69e to your computer and use it in GitHub Desktop.
from selenium import webdriver | |
from selenium.webdriver.remote.webelement import WebElement | |
import os.path | |
# JavaScript: HTML5 File drop | |
# source : https://gist.github.com/florentbr/0eff8b785e85e93ecc3ce500169bd676 | |
# param1 WebElement : Drop area element | |
# param2 Double : Optional - Drop offset x relative to the top/left corner of the drop area. Center if 0. | |
# param3 Double : Optional - Drop offset y relative to the top/left corner of the drop area. Center if 0. | |
# return WebElement : File input | |
JS_DROP_FILES = "var k=arguments,d=k[0],g=k[1],c=k[2],m=d.ownerDocument||document;for(var e=0;;){var f=d.getBoundingClientRect(),b=f.left+(g||(f.width/2)),a=f.top+(c||(f.height/2)),h=m.elementFromPoint(b,a);if(h&&d.contains(h)){break}if(++e>1){var j=new Error('Element not interactable');j.code=15;throw j}d.scrollIntoView({behavior:'instant',block:'center',inline:'center'})}var l=m.createElement('INPUT');l.setAttribute('type','file');l.setAttribute('multiple','');l.setAttribute('style','position:fixed;z-index:2147483647;left:0;top:0;');l.onchange=function(q){l.parentElement.removeChild(l);q.stopPropagation();var r={constructor:DataTransfer,effectAllowed:'all',dropEffect:'none',types:['Files'],files:l.files,setData:function u(){},getData:function o(){},clearData:function s(){},setDragImage:function i(){}};if(window.DataTransferItemList){r.items=Object.setPrototypeOf(Array.prototype.map.call(l.files,function(x){return{constructor:DataTransferItem,kind:'file',type:x.type,getAsFile:function v(){return x},getAsString:function y(A){var z=new FileReader();z.onload=function(B){A(B.target.result)};z.readAsText(x)},webkitGetAsEntry:function w(){return{constructor:FileSystemFileEntry,name:x.name,fullPath:'/'+x.name,isFile:true,isDirectory:false,file:function z(A){A(x)}}}}}),{constructor:DataTransferItemList,add:function t(){},clear:function p(){},remove:function n(){}})}['dragenter','dragover','drop'].forEach(function(v){var w=m.createEvent('DragEvent');w.initMouseEvent(v,true,true,m.defaultView,0,0,0,b,a,false,false,false,false,0,null);Object.setPrototypeOf(w,null);w.dataTransfer=r;Object.setPrototypeOf(w,DragEvent.prototype);h.dispatchEvent(w)})};m.documentElement.appendChild(l);l.getBoundingClientRect();return l" | |
def drop_files(element, files, offsetX=0, offsetY=0): | |
driver = element.parent | |
isLocal = not driver._is_remote or '127.0.0.1' in driver.command_executor._url | |
paths = [] | |
# ensure files are present, and upload to the remote server if session is remote | |
for file in (files if isinstance(files, list) else [files]) : | |
if not os.path.isfile(file) : | |
raise FileNotFoundError(file) | |
paths.append(file if isLocal else element._upload(file)) | |
value = '\n'.join(paths) | |
elm_input = driver.execute_script(JS_DROP_FILES, element, offsetX, offsetY) | |
elm_input._execute('sendKeysToElement', {'value': [value], 'text': value}) | |
WebElement.drop_files = drop_files | |
############################# USAGE EXAMPLE ############################# | |
driver = webdriver.Chrome() | |
driver.get("https://react-dropzone.js.org/") | |
dropzone = driver.find_element_by_css_selector("[data-preview='Basic example'] [style]") | |
# drop a single file | |
dropzone.drop_files("C:\\temp\\image1.png") | |
# drop two files | |
dropzone.drop_files(["C:\\temp\\image1.png", "C:\\temp\\image2.png"]) | |
# drop a file by offset | |
dropzone.drop_files("C:\\temp\\image1.png", offsetX=25, offsetY=25) | |
var args = arguments, | |
element = args[0], | |
offsetX = args[1], | |
offsetY = args[2], | |
doc = element.ownerDocument || document; | |
for (var i = 0; ;) { | |
var box = element.getBoundingClientRect(), | |
clientX = box.left + (offsetX || (box.width / 2)), | |
clientY = box.top + (offsetY || (box.height / 2)), | |
target = doc.elementFromPoint(clientX, clientY); | |
if (target && element.contains(target)) | |
break; | |
if (++i > 1) { | |
var ex = new Error('Element not interactable'); | |
ex.code = 15; | |
throw ex; | |
} | |
element.scrollIntoView({behavior: 'instant', block: 'center', inline: 'center'}); | |
} | |
var input = doc.createElement('INPUT'); | |
input.setAttribute('type', 'file'); | |
input.setAttribute('multiple', ''); | |
input.setAttribute('style', 'position:fixed;z-index:2147483647;left:0;top:0;'); | |
input.onchange = function (ev) { | |
input.parentElement.removeChild(input); | |
ev.stopPropagation(); | |
var dataTransfer = { | |
constructor : DataTransfer, | |
effectAllowed : 'all', | |
dropEffect : 'none', | |
types : [ 'Files' ], | |
files : input.files, | |
setData : function setData(){}, | |
getData : function getData(){}, | |
clearData : function clearData(){}, | |
setDragImage : function setDragImage(){} | |
}; | |
if (window.DataTransferItemList) { | |
dataTransfer.items = Object.setPrototypeOf(Array.prototype.map.call(input.files, function(f) { | |
return { | |
constructor : DataTransferItem, | |
kind : 'file', | |
type : f.type, | |
getAsFile : function getAsFile () { return f }, | |
getAsString : function getAsString (callback) { | |
var reader = new FileReader(); | |
reader.onload = function(ev) { callback(ev.target.result) }; | |
reader.readAsText(f); | |
}, | |
webkitGetAsEntry : function webkitGetAsEntry () { | |
return { | |
constructor : FileSystemFileEntry, | |
name : f.name, | |
fullPath : '/' + f.name, | |
isFile : true, | |
isDirectory : false, | |
file : function file (callback) { callback(f) } | |
} | |
} | |
} | |
}), { | |
constructor : DataTransferItemList, | |
add : function add(){}, | |
clear : function clear(){}, | |
remove : function remove(){} | |
}); | |
} | |
['dragenter', 'dragover', 'drop'].forEach(function (type) { | |
var event = doc.createEvent('DragEvent'); | |
event.initMouseEvent(type, true, true, doc.defaultView, 0, 0, 0, clientX, clientY, false, false, false, false, 0, null); | |
Object.setPrototypeOf(event, null); | |
event.dataTransfer = dataTransfer; | |
Object.setPrototypeOf(event, DragEvent.prototype); | |
target.dispatchEvent(event); | |
}); | |
}; | |
doc.documentElement.appendChild(input); | |
input.getBoundingClientRect(); /* force reflow for Firefox */ | |
return input; |
var k=arguments,d=k[0],g=k[1],c=k[2],m=d.ownerDocument||document;for(var e=0;;){var f=d.getBoundingClientRect(),b=f.left+(g||(f.width/2)),a=f.top+(c||(f.height/2)),h=m.elementFromPoint(b,a);if(h&&d.contains(h)){break}if(++e>1){var j=new Error('Element not interactable');j.code=15;throw j}d.scrollIntoView({behavior:'instant',block:'center',inline:'center'})}var l=m.createElement('INPUT');l.setAttribute('type','file');l.setAttribute('multiple','');l.setAttribute('style','position:fixed;z-index:2147483647;left:0;top:0;');l.onchange=function(q){l.parentElement.removeChild(l);q.stopPropagation();var r={constructor:DataTransfer,effectAllowed:'all',dropEffect:'none',types:['Files'],files:l.files,setData:function u(){},getData:function o(){},clearData:function s(){},setDragImage:function i(){}};if(window.DataTransferItemList){r.items=Object.setPrototypeOf(Array.prototype.map.call(l.files,function(x){return{constructor:DataTransferItem,kind:'file',type:x.type,getAsFile:function v(){return x},getAsString:function y(A){var z=new FileReader();z.onload=function(B){A(B.target.result)};z.readAsText(x)},webkitGetAsEntry:function w(){return{constructor:FileSystemFileEntry,name:x.name,fullPath:'/'+x.name,isFile:true,isDirectory:false,file:function z(A){A(x)}}}}}),{constructor:DataTransferItemList,add:function t(){},clear:function p(){},remove:function n(){}})}['dragenter','dragover','drop'].forEach(function(v){var w=m.createEvent('DragEvent');w.initMouseEvent(v,true,true,m.defaultView,0,0,0,b,a,false,false,false,false,0,null);Object.setPrototypeOf(w,null);w.dataTransfer=r;Object.setPrototypeOf(w,DragEvent.prototype);h.dispatchEvent(w)})};m.documentElement.appendChild(l);l.getBoundingClientRect();return l | |
@sandip2421, i've added the webkitGetAsEntry even though it's non standard. It should work as long as the webpage doesn't try to access the filesystem api.
I used this code in headless mode but this error occurred var ex = new Error('Element not interactable');, can you help me? thanks
@carl-pki For headless, you need to set the window size. this is what I do:
if data['headless']:
options = Options()
options.add_argument('--headless')
options.add_argument('--disable-gpu') # Last I checked this was necessary.
driver = webdriver.Chrome(options=options)
else:
driver = webdriver.Chrome()
driver.set_window_size(1547, 1102)
driver.implicitly_wait(2400)
driver.get("https://rumble.com/")
driver.find_element(..........
As You can see, I am using Chrome... But I'm sure it applies to other browsers
and trying to use this code in an implementation to upload files with this method to Google Drive but notice that it stays in this can someone try?
here the code...
`from undetected_chromedriver import Chrome
from undetected_chromedriver import ChromeOptions
from selenium.webdriver.remote.webelement import WebElement
import os
from time import sleep
opts = ChromeOptions()
opts.add_argument(f'--user-data-dir={os.getcwd()}/driver/profile')
opts.add_argument(f"--user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36")
driver = Chrome(executable_path=f'{os.getcwd()}/driver/chromedriver.exe', options=opts)
sleep(2)
driver.get('https://drive.google.com/drive/my-drive')
sleep(5)
JS_DROP_FILES = "var k=arguments,d=k[0],g=k[1],c=k[2],m=d.ownerDocument||document;for(var e=0;;){var f=d.getBoundingClientRect(),b=f.left+(g||(f.width/2)),a=f.top+(c||(f.height/2)),h=m.elementFromPoint(b,a);if(h&&d.contains(h)){break}if(++e>1){var j=new Error('Element not interactable');j.code=15;throw j}d.scrollIntoView({behavior:'instant',block:'center',inline:'center'})}var l=m.createElement('INPUT');l.setAttribute('type','file');l.setAttribute('multiple','');l.setAttribute('style','position:fixed;z-index:2147483647;left:0;top:0;');l.onchange=function(q){l.parentElement.removeChild(l);q.stopPropagation();var r={constructor:DataTransfer,effectAllowed:'all',dropEffect:'none',types:['Files'],files:l.files,setData:function u(){},getData:function o(){},clearData:function s(){},setDragImage:function i(){}};if(window.DataTransferItemList){r.items=Object.setPrototypeOf(Array.prototype.map.call(l.files,function(x){return{constructor:DataTransferItem,kind:'file',type:x.type,getAsFile:function v(){return x},getAsString:function y(A){var z=new FileReader();z.onload=function(B){A(B.target.result)};z.readAsText(x)},webkitGetAsEntry:function w(){return{constructor:FileSystemFileEntry,name:x.name,fullPath:'/'+x.name,isFile:true,isDirectory:false,file:function z(A){A(x)}}}}}),{constructor:DataTransferItemList,add:function t(){},clear:function p(){},remove:function n(){}})}['dragenter','dragover','drop'].forEach(function(v){var w=m.createEvent('DragEvent');w.initMouseEvent(v,true,true,m.defaultView,0,0,0,b,a,false,false,false,false,0,null);Object.setPrototypeOf(w,null);w.dataTransfer=r;Object.setPrototypeOf(w,DragEvent.prototype);h.dispatchEvent(w)})};m.documentElement.appendChild(l);l.getBoundingClientRect();return l"
def drop_files(element, files, offsetX=0, offsetY=0):
driver = element.parent
isLocal = not driver._is_remote or '127.0.0.1' in driver.command_executor._url
paths = []
# ensure files are present, and upload to the remote server if session is remote
for file in (files if isinstance(files, list) else [files]):
if not os.path.isfile(file):
raise FileNotFoundError(file)
paths.append(file if isLocal else element._upload(file))
value = '\n'.join(paths)
elm_input = driver.execute_script(JS_DROP_FILES, element, offsetX, offsetY)
elm_input._execute('sendKeysToElement', {'value': [value], 'text': value})
WebElement.drop_files = drop_files
dropzone = driver.find_element_by_xpath('//c-wiz[@data-region-root]')
dropzone.drop_files(f'{os.getcwd()}\downloads\english.srt')`
with this code it stays on this screen and does not go up.
worked straight out of the box!! o7
the only solution on the internet that actually solves the problem without beating around the bush.
Hi guys,
I tried to test it and get the error message.
selenium.common.exceptions.WebDriverException: Message: <unknown>: Element not interactable
Can any one can help me resolve it?
Frikkn unbelievable thank you!
not working for me .. getting error TypeError e.webkitGetAsEntry is not a function (java)