如何使用Python请求实现ajax请求

2024-06-10 10:51:10 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在尝试使用Python请求登录到一个网站。不幸的是,它在打印内容时总是显示此错误

b'<head><title>Not Acceptable!</title></head><body><h1>Not Acceptable!</h1><p>An appropriate representation of the requested resource could not be found on this server. This error was generated by Mod_Security.</p></body></html>

参考我的代码

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)

我可以知道缺少了什么,以及如何从这个页面获取欢迎页面的HTML代码吗

更新

我正在尝试在登录身份验证后进行API调用。但是,我无法成功进行登录身份验证。因此,我无法获得API调用的响应。根据我的想法,由于多因素身份验证,它正在失败。我需要知道如何实现这一点

例如:www.abc.com是网站的URL。登录是通过JS表单提交完成的,因此URL在ajax部分中指定。一旦成功,还有另一个第三方身份验证方(okta)也将验证凭据并最终到达主页。然后我需要为我的任务调用真正的API

但它不起作用

import requests
import sys
class Login:

     def sendRequestWithAuthentication(self,loginDetails,requestDetails):
         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'}
         action_url=loginDetails['action_url'] if 'action_url' in loginDetails.keys() else None
         pay_load=loginDetails['payload'] if 'payload' in loginDetails.keys() else None
         session_requests = requests.session()
         if action_url and pay_load:
             act_resp=session_requests.post(action_url, data=pay_load, headers=user_agent,verify=False,files=[ ])
             print(act_resp)
             auth_cookies=act_resp.cookies.get_dict()
             url,method,request_payload = requestDetails['url'],requestDetails['method'],requestDetails['payload']
             querystring=requestDetails['querystring']
             response=session_requests.get(url,headers=user_agent,cookies=auth_cookies,data=request_payload,params=querystring)
             print(response)
             return response.json()

在上面的操作中,URL是ajax部分中给出的API&;在第二个请求中,URL是该GET的API地址

简而言之,我可以知道如何在python请求中实现多因素身份验证吗

我的怀疑

  1. 我们是否需要登录表单页面中的cookies来包含在登录请求中
  2. 如何在python请求中实现多因素身份验证(这里我们不需要任何pin或通过RSA完成的操作)。由于现在无法验证SSL证书,登录是否需要证书

给出一个实现此类场景的虚拟示例api


Tags: com身份验证apiurlloginajaxrequestsagent
3条回答

不,你让它变得复杂。这段代码有效:

import requests

login_url = "https://phpzag.com/demo/ajax_login_script_with_php_jquery/login.php"
welcome_url = "https://phpzag.com/demo/ajax_login_script_with_php_jquery/welcome.php"

payload = 'user_email=test@phpzag.com&password=test&login_button='
login_headers = {
    'x-requested-with': 'XMLHttpRequest',
    'Content-Type': 'application/x-www-form-urlencoded', # its urlencoded instead of form-data
    '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',
}
s = requests.Session()
login = s.post(login_url, headers=login_headers, data=payload) # post requests
welcome = s.get(welcome_url, headers=login_headers)
print(welcome.text)

结果:

.....Hello, <br><br>Welcome to the members page.<br><br>

您缺少服务器(apache?)所需的用户代理

试试这个:

import requests
from requests import Session

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'}
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'}

s = requests.Session()
x=s.get(URL, headers=user_agent)
x=s.post(LOGIN_URL, data=payload, headers=user_agent)
print(x.content)
print(x.status_code)

TL;博士

将代码中表示data=payload的部分更改为json=payload,它应该可以工作

直接回答你的问题

How [does one] implement [an] AJAX request using Python Requests?

你不能那样做。AJAX请求特别指基于Javascript的HTTP请求。引用W3 school's AJAX introduction page,“AJAX=异步JavaScript和XML”

对你问题的间接回答

我相信您要问的是如何使用流行的python包^{}执行身份验证/登录HTTP请求。简而言之,不幸的是,就像大多数事情一样,这要视情况而定。不同的身份验证页以不同的方式处理身份验证请求,因此您可能必须执行不同的操作才能针对特定的web服务进行身份验证

基于您的代码

我将根据您的代码和response back from the server being a 406 error这意味着您发送的数据带有与服务器想要响应的方式不一致的accept标头,这意味着登录页面可能正在寻找一个带有JSON对象形式的身份验证详细信息(例如凭据)的POST请求

使用请求时,使用data参数到请求函数将发送数据“raw”;也就是说,它将以本机数据格式发送它(就像二进制数据的情况一样),或者如果该格式不起作用,它将把它转换为标准HTML表单数据(例如key1=value1&key2=value2&key3=value3,此表单的MIME类型为application/x-www-form-urlencoded,并且是当data未使用accept头指定时请求将发送的内容)。我将根据这样一个事实做出一个有根据的猜测,即您将凭证放入字典中,登录表单需要一个带有JSON格式正文的POST请求(大多数现代web应用程序都会这样做),您的印象是,将data参数设置为requests将使其成为JSON对象。这是一种常见的误解/误解,以前有过这样的请求。您需要的是使用json参数传递数据

您的代码:

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)

固定(和清理)代码:

#!/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)

检查一下this section of the requests documentation on POST requests,如果您从那里向下滚动一点,您将看到文档讨论期望JSON的github API以及如何处理它

总体而言,Auth可能很棘手。有时需要“basic auth”,请求希望您将它作为tuple传递给auth参数,有时需要一个承载令牌/OAUTH,这可能会变得非常复杂/烦人

希望这有帮助

相关问题 更多 >