<h2>TL;博士</h2>
<p>将代码中表示<code>data=payload</code>的部分更改为<code>json=payload</code>,它应该可以工作</p>
<h2>直接回答你的问题</h2>
<blockquote>
<p>How [does one] implement [an] AJAX request using Python Requests?</p>
</blockquote>
<p>你不能那样做。AJAX请求特别指基于Javascript的HTTP请求。引用<a href="https://www.w3schools.com/xml/ajax_intro.asp" rel="nofollow noreferrer">W3 school's AJAX introduction page</a>,“AJAX=异步JavaScript和XML”</p>
<h2>对你问题的间接回答</h2>
<p>我相信您要问的是如何使用流行的python包<a href="https://2.python-requests.org/en/master/" rel="nofollow noreferrer">^{<cd3>}</a>执行身份验证/登录HTTP请求。简而言之,不幸的是,就像大多数事情一样,这要视情况而定。不同的身份验证页以不同的方式处理身份验证请求,因此您可能必须执行不同的操作才能针对特定的web服务进行身份验证</p>
<h3>基于您的代码</h3>
<p>我将根据您的代码和<a href="https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#4xx_Client_errors" rel="nofollow noreferrer">response back from the server being a 406 error</a>这意味着您发送的数据带有与服务器想要响应的方式不一致的accept标头,这意味着登录页面可能正在寻找一个带有JSON对象形式的身份验证详细信息(例如凭据)的POST请求</p>
<p>使用请求时,使用<code>data</code>参数到请求函数将发送数据“raw”;也就是说,它将以本机数据格式发送它(就像二进制数据的情况一样),或者如果该格式不起作用,它将把它转换为标准HTML表单数据(例如<code>key1=value1&key2=value2&key3=value3</code>,此表单的MIME类型为<code>application/x-www-form-urlencoded</code>,并且是当<code>data</code>未使用<code>accept</code>头指定时请求将发送的内容)。我将根据这样一个事实做出一个有根据的猜测,即您将凭证放入字典中,登录表单需要一个带有JSON格式正文的POST请求(大多数现代web应用程序都会这样做),您的印象是,将<code>data</code>参数设置为requests将使其成为JSON对象。这是一种常见的误解/误解,以前有过这样的请求。您需要的是使用<code>json</code>参数传递数据</p>
<p>您的代码:</p>
<pre class="lang-py prettyprint-override"><code>from requests import Session
import requests
INDEX_URL = 'https://phpzag.com/demo/ajax_login_script_with_php_jquery/index.php'
URL = 'https://phpzag.com/demo/ajax_login_script_with_php_jquery/welcome.php'
LOGIN_URL = 'https://phpzag.com/demo/ajax_login_script_with_php_jquery/login.php' # Or whatever the login request url is
payload = {'user_email': 'test@phpzag.com','password':'test'}
s = requests.Session()
user_agent = {'User-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.129 Safari/537.36'}
t=s.post(LOGIN_URL, data=payload, headers=user_agent)
r=s.get('https://phpzag.com/demo/ajax_login_script_with_php_jquery/welcome.php',headers=user_agent,cookies=t.cookies.get_dict())
print(r.content)
</code></pre>
<p>固定(和清理)代码:</p>
<pre class="lang-py prettyprint-override"><code>#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Test script to login to php web app.
"""
import requests
INDEX_URL = 'https://phpzag.com/demo/ajax_login_script_with_php_jquery/index.php'
URL = 'https://phpzag.com/demo/ajax_login_script_with_php_jquery/welcome.php'
LOGIN_URL = 'https://phpzag.com/demo/ajax_login_script_with_php_jquery/login.php' # Or whatever the login request url is
payload = {
'user_email': 'test@phpzag.com',
'password':'test'
}
headers = {
'User-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.129 Safari/537.36'
}
session = requests.Session()
auth_response = session.post(
url=LOGIN_URL,
json=payload, # <--- THIS IS THE IMPORTANT BIT. Note: data param changed to json param
headers=user_agent
)
response = session.get(
'https://phpzag.com/demo/ajax_login_script_with_php_jquery/welcome.php',
headers=headers,
cookies=auth_response.cookies.get_dict() # TODO: not sure this is necessary, since you're using the session object to initiate the request, so that should maintain the cookies/session data throughout the session...
)
print(response.content)
</code></pre>
<p>检查一下<a href="https://2.python-requests.org/en/master/user/quickstart/#more-complicated-post-requests" rel="nofollow noreferrer">this section of the requests documentation on POST requests</a>,如果您从那里向下滚动一点,您将看到文档讨论期望JSON的github API以及如何处理它</p>
<p>总体而言,Auth可能很棘手。有时需要“basic auth”,请求希望您将它作为<code>tuple</code>传递给<code>auth</code>参数,有时需要一个承载令牌/OAUTH,这可能会变得非常复杂/烦人</p>
<p>希望这有帮助</p>