0

I can use Selenium to upload a file as

from selenium import webdriver

driver = webdriver.Chrome()
driver.get(r'https://www.example.com')
a = driver.find_element_by_xpath("//input[@type='file']")
a.send_keys(r'C:\abc.jpg')
b =  driver.find_element_by_xpath("//output[@id='result']").text

The above code works well.

Now, I want to use Requests to the same job. I tried to search on the web and implement the code. But I cannot get the result.

import requests
from lxml import html

a = requests.get(r'https://www.example.com')
tree = html.fromstring(a.text)
b = tree.xpath("//input[@type='file']")
b.append(r'C:\abc.jpg')#Is it correct?

The html code is as follows:

<div id="test" class="abc def ghi">
    <div class="xyz def ghi">
        Drag or<br class="def ghi">Click to input file
    </div>
    <div class="pqr def ghi">
        Upload file
    </div>
    <label id="select-file" for="input" class="def ghi"></label>
    <input type="file" id="input" hidden="" class="def ghi">
</div>

There is no form in the code. How to solve the problem?

5
  • 1
    this answer may help. you'd neet to requests.post your (encoded) image. Commented Mar 20, 2018 at 7:31
  • to send data whatever type to the server, you should use 'post' function. docs.python-requests.org/en/master/user/quickstart/… Commented Mar 20, 2018 at 7:36
  • The example writes: requests.post(url, params=params, data=json.dumps(data), headers=headers) and data = {"eventType": "AAS_PORTAL_START", "data": {"uid": "hfe3hf45huf33545", "aid": "1", "vid": "1"}}. But I don't know how to pass in the required dictionary in my case. Is it data={"//input[@type='file']": r'C:\abc.jpg' }? Commented Mar 20, 2018 at 7:48
  • Can anyone please help? Commented Mar 20, 2018 at 9:06
  • Assuming you want to post a file, try something like this: requests.post('https://www.example.com', files={b.attrib['name']: open(r'C:\abc.jpg', 'rb')}) Commented Mar 20, 2018 at 17:17

1 Answer 1

2

You need to use files parameter. Also form's action attribute can specify different upload url, so it's better to check it out.

Here's full example:

import requests
from lxml import html

host = r'https://www.example.com'
url = '/'
filename = r'C:\abc.jpg'


req = requests.get(host + url)

tree = html.fromstring(req.text)
field = tree.xpath("//input[@type='file']")
form = next(f[0].iterancestors("form"), None)
action = form.attrib['action'] if form else url

requests.post(host + action,
              files={filename: (open(filename, 'rb'), 'image/jpg')})
Sign up to request clarification or add additional context in comments.

3 Comments

Thank you, Nikita. I tried to run your code. However, I got the error: form = list(f[0].iterancestors("form"))[0] IndexError: list index out of range because ist(f[0].iterancestors("form")) equals []
I have included the html. Any suggestions?
Hi, Chan. It's not a common case when there's no form. There should be some script processing the field. Anyway, i've edited my answer to address your case more precisely

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.