I am trying to post form data to a URL. I am not getting the expected response and curious about some information I am getting from requests module (2.6.2). The following is the post method:
>>> response = requests.post(url, data={'uname':user, 'pwd':password,'phrase':'','submit':True})
As you can see I am using the post() method, so I expected the method to be POST. The keys for the data object match the names of the form elements. The URL is the form action.
>>> vars(response.request)
{'method': 'GET', 'body': None, '_cookies': <<class 'requests.cookies.RequestsCookieJar'>[]>, 'headers': {'Accept-Encoding': 'gzip, deflate', 'Accept': '*/*', 'Content-Type': 'application/x-www-form-urlencoded', 'User-Agent': 'python-requests/2.6.2 CPython/3.3.6 Windows/8', 'Connection': 'keep-alive'}, 'hooks': {'response': []}, 'url': url}
The response.request property should contain information about the request that was sent for this response. It's method property is GET, I expected POST. The URL looks correct. The page is expected to return something else if the form posts though, strange, I'll check the request headers.
>>> response.request.headers
{'Accept-Encoding': 'gzip, deflate', 'Accept': '*/*', 'Content-Type': 'application/x-www-form-urlencoded', 'User-Agent': 'python-requests/2.6.2 CPython/3.3.6 Windows/8', 'Connection': 'keep-alive'}
>>>
Those look OK except, wait a minute! Where is my form data? Why is it not being sent with the request? I check the history and find I am being redirected. This time I add allow_redirects=False to my post() call. Then check the response.request object and its headers.
>>> vars(response.request)
{'method': 'POST', 'body': 'phrase=&pwd=****&uname=****&submit=True', '_cookies': <<class 'requests.cookies.RequestsCookieJar'>[]>, 'headers': {'Accept-Encoding': 'gzip, deflate', 'Content-Type': 'application/x-www-form-urlencoded', 'User-Agent': 'python-requests/2.6.2 CPython/3.3.6 Windows/8', 'Content-Length': '56', 'Accept': '*/*', 'Connection': 'keep-alive'}, 'hooks': {'response': []}, 'url': 'http://myurl.com/path/to/script.php'}
This time it's a POST so that seems correct. I feel like I'm on the right track. That's strange, the body property appears like a query string, not like I'd expect for a form post.
>>> response.request.headers
{'Accept-Encoding': 'gzip, deflate', 'Content-Type': 'application/x-www-form-urlencoded', 'User-Agent': 'python-requests/2.6.2 CPython/3.3.6 Windows/8', 'Content-Length': '56', 'Accept': '*/*', 'Connection': 'keep-alive'}
Those headers, again no form data in the header. What's this? 'Content-Type': 'application/x-www-form-urlencoded'? Is that why my form data looks like a query string? What would a normal content-type be? It's the same type as reported by Chrome hitting the same URL so I doubt that's the issue.
If none of this looks off, they may be smart and rejecting a post from a non-local origin right? My main concern is that the form data is a string in the body property, that seems wrong. If not, can I get clever and set the HTTP header origin?
.post(headers={'origin':...,'host':..., ...})and it made no difference.