Automate file upload using Selenium and ng-file-upload - python

I have a project where I am uploading photos via ng-file-upload and I need to automate the upload process with selenium webdriver in Python.
my HTML element looks like this:
<element
ngf-pattern="image/*" accept="image/*"
ngf-max-size="10MB" ngf-max-height="1000" ngf-select="addPhoto($index, $file)">
...</element>
Uploading the element definitely works when doing it manually. But I cannot find a way to automate this using Selenium in Python. I have tried finding the element, then sending the keys of the image's absolute path, but that just puts the absolute path in the browser's search field (as if I typed "Command + F" on Mac)
Note that there is no
<input type="file"/>
with this method of uploading a file.
Any ideas how to do this in Python using Selenium? Thanks!

There has to be a file input hidden which is implicitly responsible for the file upload. For instance, the angular-file-upload DEMO page has it hidden at the bottom of a page.
Here is a working example:
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
driver = webdriver.Chrome()
driver.get("https://angular-file-upload.appspot.com/")
# wait for the upload box to be visible
wait = WebDriverWait(driver, 10)
element = wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, "div[ngf-select]")))
# get a model
model = element.get_attribute("ng-model")
# find a file input by model
file_input = driver.find_element_by_css_selector('input[ngf-select][ng-model="%s"]' % model)
# upload an image
file_input.send_keys("/absolute/path/to/dr-evil-and-minion-laughing.png")
Results into:

Related

Upload picture in selenium without input[type="file=] element

I'm trying to automate the process to upload the pictures on remove.bg but I'm unable to find the input field for the file in inspect elements. I know that by using input and send_keys we can automate this but what should I do in this case when the input field is not visible. This is what I've tried till now.
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.keys import Keys
from selenium import webdriver
driver = webdriver.Firefox()
test = driver.get("https://www.remove.bg/upload")
input = driver.find_element_by_xpath('//input[#type="file"]')
print (input)
#send_keys below.
it looks like it is a production system. Do you have permission to automate this site?

file upload without <input type="file"> element in Selenium

I'm trying to automate the process to upload the pictures on remove.bg but I'm unable to find the input field for the file in inspect elements. I know that by using input and send_keys we can automate this but what should I do in this case when the input field is not visible. This is what I've tried till now.
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.keys import Keys
from selenium import webdriver
driver = webdriver.Firefox()
test = driver.get("https://www.remove.bg/upload")
input = driver.find_element_by_xpath('//input[#type="file"]')
print (input)
Can you please try the following xpath to click the upload button because there is no input tag in that website.
//button[contains(text(),'Upload Image')]

selenium - trouble clicking a button to export

I've been learning how to use selenium to parse data and I've been doing alright with that process. So I'm trying something different, in that I found data ta parse, but there is a provided export button which to me, sounds like a quicker solution, so I thought I'd have a stab at it. But I'm not quite understanding how it's not working:
browser = webdriver.Chrome()
url = 'https://www.rotowire.com/football/injury-report.php'
browser.get(url)
button = browser.find_elements_by_xpath('//*[#id="injury-report"]/div[2]/div[2]/button[2]')
button.click()
browser.close()
I just want to click on the export csv button on the page.
Also, I haven't looked yet, but my next step would be to specify where to save the csv file it exports. Right now it, defaults to the downloads folder. Is there a way to specify a location without changing the default? Also is there a way to specify a file name?
Try below code to click required button:
from selenium.webdriver.support.ui import WebDriverWait as wait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
browser = webdriver.Chrome()
url = 'https://www.rotowire.com/football/injury-report.php'
browser.get(url)
button = wait(browser, 10).until(EC.element_to_be_clickable((By.CLASS_NAME, "is-csv")))
button.click()
browser.close()
Also check how to save file to specific folder

Selenium/Python - Extract dynamically generated HTML after submitting form

The web page I am trying to access is using JavaScript to dynamically generate HTML form(this one: https://imgur.com/a/rhmXB ). When typing print(page_source), the table seems to appear in the HTML being outputted.
However, after filling the input field and submitting the form, another input field with CAPTCHA image appears(as shown here: https://imgur.com/a/xVfBS ). After typing print(page_source), the input form with the CAPTCHA seems not to be inserted into the HTML.
My question is: How can I access this dynamically generated HTML, which contains the input field and the CAPTCHA image using Selenium?
Here is my code (also, in pastebin):
from selenium import webdriver
driver = webdriver.Chrome("/var/chromedriver/chromedriver")
URL = 'http://nap.bg/link?id=104'
driver.get(URL)
input_field = driver.find_element_by_name('ipID')
input_field.send_keys('0000000000')
driver.find_element_by_id('idSubmit').click()
print(driver.page_source)
After you click on the button, the page takes some time to load the CAPTCHA and other content. You'll need to wait for that to finish loading. You can do that using Selenium's explicit waits.
This is an example for what you can do:
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
driver = webdriver.Chrome()
URL = 'http://nap.bg/link?id=104'
driver.get(URL)
input_field = driver.find_element_by_name('ipID')
input_field.send_keys('0000000000')
driver.find_element_by_id('idSubmit').click()
wait = WebDriverWait(driver, 10)
wait.until(EC.element_to_be_clickable((By.NAME, 'ipResponse')))
print(driver.page_source)

How can I scrape this?

I need to scrape this page (which has a form): http://kllads.kar.nic.in/MLAWise_reports.aspx, with Python preferably (if not Python, then JavaScript). I was looking at libraries like RoboBrowser (which is basically Mechanize + BeautifulSoup) and (maybe) Selenium but I'm not quite sure on how to go about it. From inspecting the element, it seems to be a WebForm that I need to fill in. After filling that in, the webpage generates some data that I need to store. How should I do this?
You can interact with the javascript web forms relatively easily in Selenium. You may need to install a webdriver quickly, but besides that all you need to do is find the form using its xpath and then have Selenium select an option from the drop down menu using the option's xpath. For the web page provided that would look something like this:
#import functions from selenium module
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
# open chrome browser using webdriver
path_to_chromedriver = '/Users/Michael/Downloads/chromedriver'
browser = webdriver.Chrome(executable_path=path_to_chromedriver)
# open web page using browser
browser.get('http://kllads.kar.nic.in/MLAWise_reports.aspx')
# wait for page to load then find 'Constituency Name' dropdown and select 'Aland (46)''
const_name = WebDriverWait(browser, 20).until(EC.element_to_be_clickable((By.XPATH, '//*[#id="ddlconstname"]')))
browser.find_element_by_xpath('//*[#id="ddlconstname"]/option[2]').click()
# wait for the page to load then find 'Select Status' dropdown and select 'OnGoing'
sel_status = WebDriverWait(browser, 20).until(EC.element_to_be_clickable((By.XPATH, '//*[#id="ddlstatus1"]')))
browser.find_element_by_xpath('//*[#id="ddlstatus1"]/option[2]').click()
# wait for browser to load then click 'Generate Report'
gen_report = WebDriverWait(browser, 20).until(EC.element_to_be_clickable((By.XPATH, '//*[#id="BtnReport"]')))
browser.find_element_by_xpath('//*[#id="BtnReport"]').click()
Between each interaction, you are just giving the browser some time to load before attempting click the next element. Once all the forms are filled out, the page will display the data based on the options selected and you should be able to scrape the table data. I had a few issues when attempting to load data for the first Constituency Name option, but the others seemed to work fine.
You should also be able to loop through all the dropdown options available under each web form to display all the data.
Hope that helps!

Categories