3

I'm testing some web scraping on Instagram with Selenium and Python.

In this case I want to upload a picture.

Normally you have to click on the upload icon and choose the file from a window. How can I manage it with Selenium?

I tried:

driver.find_element_by_class_name("coreSpriteFeedCreation").send_keys('C:\\path-to-file\\file.jpg')

and also with find_element_by_xpath but I get an exception:

selenium.common.exceptions.WebDriverException: Message: unknown error: cannot focus element

I tried also only with click() but nothing happens.

Any Idea?

EDIT
Thanks to @homersimpson comment I tried this:

actions = ActionChains(driver)
element = driver.find_element_by_class_name("coreSpriteFeedCreation")
actions.move_to_element(element)
actions.click()
actions.send_keys('C:\\path-to-file\\file.jpg')
actions.perform()

Now the window to choose the file appears. The problem is that I would like to avoid this window and give directly the path of my file.

3
  • There might be an answer here: stackoverflow.com/a/34547262/1530072 Commented Jun 18, 2018 at 14:40
  • thanks @homersimpson , I edited my question Commented Jun 18, 2018 at 14:57
  • Are you able to show an HTML snippet of the file upload window? Commented Jun 18, 2018 at 15:02

3 Answers 3

5

If right understand, you are trying to avoid handling with a native window. You can try this:

# get all inputs
inputs = driver.find_elements_by_xpath("//input[@accept = 'image/jpeg']").send_keys(os.getcwd() + "/image.png")

Now you can try all of them. I don't know which of them will work.

More about os.getcwd() is here

To be able to perform this code you have to have an element like this:

<input type="file" name="fileToUpload" id="fileToUpload2" class="fileToUpload">

EDIT:

It looks like instagram turned of input fields interaction for posts. For Account image it still works, but not for posting. I assume it is was done to prevent bots to post images. Anyway, there is a solution for this problem. You can use AutoIt like this:

import autoit
from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.keys import Keys

ActionChains(driver).move_to_element( driver.find_element_by_xpath("//path/to/upload/button")).click().perform()
handle = "[CLASS:#32770; TITLE:Open]"
autoit.win_wait(handle, 60)
autoit.control_set_text(handle, "Edit1", "\\file\\path")
autoit.control_click(handle, "Button1")
Sign up to request clarification or add additional context in comments.

9 Comments

I get always selenium.common.exceptions.WebDriverException: Message: unknown error: cannot focus element
Happy to hear it, today I have reached limit of down/upvotes, so tomorrow I'll upvote your question. You have a good one )
@AndreiSuvorkov : I'll do it for you.
Little problem, it works perfectly but it opens the wrong input. With your code I can change my profile picture. I tried all the input in the DOM without success. Any ideas?
I have changed my xPath. So I have found three elements according new xPath. I don't know which of them is the right one, but one of them should do the trick. Please try and tell me if it works, and which element was the right one.
|
1

I think I may have found a solution that works for me. I found if you first have the bot click the plus icon while the browser is in the mobile view.

self.driver.find_element_by_xpath("/html/body/div[1]/section/nav[2]/div/div/div[2]/div/div/div[3]")\
        .click()

after that, I would immediately send my file to an input tag in the HTML and I find you may need to play around as to which one works but I find the last input tag worked for me.

self.driver.find_element_by_xpath("/html/body/div[1]/section/nav[2]/div/div/form/input")\
        .send_keys("/image/path.jpg")

The one weird thing about this is you will have a popup menu on top of the page but your code will still function with this window displayed over the window you are working on.

Comments

1

Addition to HumbleFox's answer. To solve his problem regarding the pop-up box not closing or the file pop-up box not closing (bug)

The solution to this is to make the browser headless here's a part of my code for example:

mobile_emulation = { "deviceName": "Pixel 2" }
chrome_options = webdriver.ChromeOptions()
chrome_options.add_argument('--headless')
chrome_options.add_experimental_option("mobileEmulation", mobile_emulation)
chrome_options.binary_location = self.opt.binary_location
self.driver = webdriver.Chrome(executable_path=self.path, options=chrome_options)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.