How to send multidimensional POST in Python - python

I use requests.api lib to send post request. What I want is to send multidimensional POST data and I always come up short with this code:
import requests
url = 'http://someurl.com';
request_data = {}
request_data['someKey'] = 'someData'
request_data['someKeytwo'] = 'someData2'
request_data['requestData'] = {'someKey3': 'someData3'}
login = requests.post(url, data=login_data)
On the receiving end i get a POST with "requestData" => "someKey3" instead of "requestData" => ["someKey3" => 'someData3']
How do I send the correct POST?

The correct answer for my question is:
import requests
url = 'http://someurl.com';
request_data = {}
request_data['requestData[someKey3]'] = 'someData3'
login = requests.post(url, data=request_data)

Simply use:
import json
login = requests.post(rul, data=json.dumps(login_data))
This way you receive a json on the the receiving side.

Related

Can not fill form using python requests

I am trying to fill html form and get the intended result as i get when i fill manually. But I fail.
I am trying to fill the site https://www.desco.org.bd/ebill/login.php with value 32000001. So far my try is as below-
import requests
#LOGIN_URL = 'https://www.desco.org.bd/ebill/login.php'
#LOGIN_URL = 'https://www.desco.org.bd/ebill/authentication.php'
LOGIN_URL = 'https://www.desco.org.bd/ebill/billinformation.php'
payload = {
'username': '32000001',
'login':'Login',
'login':'true'
}
with requests.Session() as s:
p = s.post(LOGIN_URL, data=payload)#, verify=False)
# print the html returned or something more intelligent to see if it's a successful login page.
print (p.text)
I have found that login.php redirects to authentication.php and it further redirects to billinformation.php which delivers the true data i needed.
Thanks in advance.
N.B. I am not planning to use selenium since it is too slow for my case i.e. collect huge data from this site.
i am working for similar case, may be you would try using websockets:
import websockets
def process_function(message):
# process the message
def server(ws:str, path:int):
while True:
message_received = await ws.recv() # receive from ui
print(f'Msg [{message_received}]')
message_to_send = process_function(message)
await ws.send(message_to_send) # send feedback to ui
server = websockets.serve(server, '127.0.0.1', 5678) # set the html to run in the same ip:port
another try:
import json, requests
def do_auth(url):
headers = {"Content-Type": "application/json", "Accept":'*/*'}
body = json.dumps({'username': 'user', 'password': 'pass'})
r = requests.post(url=url, headers=headers, data=body, verify=False)
print(r.status_code);
d = json.loads(r.text);
print(d['access_token']);
print(d['refresh_token'])
return d['access_token'], d['refresh_token']
do_auth(url_auth) # authorization
requests.get(url_content, headers=headers, verify=False) # get data

Django view doesn't receive Json data?

Using a simple Python script, i want to send a request, with Python-Requests, to a Django view. The Django view should receive the json data inside the request and should print it to my console; here is what i tried:
This is how i send the request:
url = 'http://127.0.0.1:8000/myview/view'
client = requests.session()
csrftoken = requests.get(url).cookies['csrftoken']
data = json.dumps({'data': 'test-value'})
header = {'X-CSRFToken': csrftoken}
cookies = {'csrftoken': csrftoken}
resp = requests.post(url, data=data, headers=header, cookies=cookies)
And this is how the Django view receives it:
def myview(request):
if request.method == 'POST':
data = request.POST.get('data')
print(data)
print('received.')
response = HttpResponse(get_token(request))
return response
The problem with my current code is that print(data) will throw the following output:
None
received.
[06/Jan/2020 21:23:57] "POST /myview/view HTTP/1.1" 200 64
So, instead of printing test-value, it prints nothing. I don't understand whether the error is in my Django view or in how i'm sending the request. Any advice is appreciated!
The problem is with your request, and entirely caused by this line:
data = json.dumps({'data': 'test-value'})
You simply want
data = {'data': 'test-value'}
The POST data should be sent as a simple dictionary, not a JSON string - see the documentation and example here.

POST Line-based text data: text/plain

Currently trying to manage a website with a Python script to control IoT object.
From what I discovered, control is doing in 2 times :
POST method to get an ID, needed to control the device.
POST method using the ID
The first one is working with this Python script and ID is displayed in the response.
import requests
url = 'http://local_IP/login.cgi'
payload = {'lgname': 'theLogin', 'lgpin': 'thePin'}
r = requests.post(url, data=payload)
For the second POST (to control the device when the user is logged in), I captured the command with Wireshark and here is the information:
POST /user/keyfunction.cgi HTTP/1.1\r\n
Content-Type: text/plain;charset=UTF-8\r\n
Referer: http://LOCAL_IP/login.cgi\r\n
and then I have:
Line-based text data: text/plain
sess=IDReceivedWithTheFirstPOST&comm=80&Data0=2&data2=18&data1=1
So basicaly, I need a way to do a POST in Python with this "Line-based text data: text/plain" but I have no idea how to deal with it.
Hope you'll be able to help me,
Thank you,
Baptiste
EDIT: If it can help anyone someday, here is my working code:
import requests
from collections import OrderedDict
session = requests.Session()
url = 'http://LOCAL_IP/login.cgi'
payload = {'lgname': 'User', 'lgpin': 'Password'}
r_login = session.post(url, data=payload)
with open('data.txt', 'w') as output:
output.write(r_login.text)
text = 'function getSession(){return'
with open('./data.txt', 'rb') as f:
for line in f:
if line.find(text) == 1:
id = line.split()[2][1:17]
print(id)
data = OrderedDict()
data['sess']=id
data['comm']=80
data['data0']=2
data['data2']=1
data['data1']=16
url = 'http://LOCAL_IP/user/keyfunction.cgi'
r_keyfunction = session.post(url, data=data)
with open('data2.txt', 'w') as output:
output.write(r_keyfunction.text)
Updated based on OPs results to use requests.Session()
using requests.Session() will capture all cookies and forward them on subsequent requests. It also pools connections and does lots of other cool things.
import requests
session = requests.Session()
payload = {'lgname': 'theLogin', 'lgpin': 'thePin'}
r_login = session.post('http://local_IP/login.cgi', data=payload)
# Figure out the ID here somehow
id_thing = 'IDReceivedWithTheFirstPOST'
payload = {
'sess': id_thing,
'comm': 80,
'Data0': 2,
'data2': 18,
'data1': 1
}
r_keyfunction = session.post('http://local_IP/user/keyfunction.cgi', params=payload)
# do something here

Sending POST request with payload using a module requests

How to send a POST request with this payload (optional: with file)? Should I send all of headers for proper work of it?
This doesn't work:
data = {"to":"6642","send":"1","go":"1","id":"6642"}
f = open("f.jpg","rb")
r = requests.post(url,data=data,files={"f.jpg":f})
parameters and payload
Sorry for my English and thanks for answers!
Check this, I hope you attached the whole payload.
data = {'to':'6642',
'send'='1',
'go':'1',
'id':'6642',
"walltext":"TEST",
"wallsend":"TEST"}
files = {'file2':open("f.jpg","rb")
r = requests.post(url,data=data,files = files)

Post array as parameters for API call

I am trying to send a tweet to the Buffer API using the POST /updates/create method. I get a 405 error as a response. I think the problem comes from the profile_ids parameter which should be an array. What is the correct syntax for this case ?
import requests
import json
url = "https://api.bufferapp.com/1/updates/create.json"
params = dict()
params['access_token'] = myToken
params["profile_ids"] = myID
params['text']= "This is a test"
r = requests.post(url, params=params)
print(r.status_code)
Please note that myToken and myID are variables I did not share for the post.

Categories