Как реализовать запрос ajax с помощью Python запроса - PullRequest
7 голосов
/ 05 мая 2020

Я пытаюсь зайти на сайт с помощью запроса 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 код страницы приветствия с этой

UPDATE

Я пытаюсь выполнить вызов 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-адресе действия указан API, указанный в части ajax и в второй запрос, URL - это адрес API для этого GET.

Короче говоря, могу ли я узнать, как реализовать многофакторную аутентификацию в python запросе

My Doubt

  1. Нужны ли нам файлы cookie со страницы формы входа в систему для включения в запрос на вход?
  2. Как реализовать многофакторную аутентификацию в запросе python (здесь нам не нужен пин-код или что-то еще RSA.) Есть ли необходимость в сертификате для входа в систему, поскольку теперь он не может проверить сертификат SSL

Приведите фиктивный пример api, который реализует такой сценарий

Ответы [ 4 ]

5 голосов
/ 01 июня 2020

Нет, вы усложняете. Этот код сработал:

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>
1 голос
/ 05 июня 2020

TL; DR

Измените часть вашего кода, которая говорит data=payload на json=payload, и он должен работать.

Прямой ответ на ваш вопрос

Как [можно] реализовать [] AJAX запрос, используя Python Запросы?

Вы не можете этого сделать. Запрос AJAX конкретно относится к HTTP-запросу на основе Javascript. Цитата из W3 school AJAX вводной страницы , «AJAX = Асинхронный JavaScript И XML».

Косвенный ответ на ваш вопрос

Что Я полагаю, вы спрашиваете, как выполнять HTTP-запросы аутентификации / входа в систему, используя популярный пакет python, requests. Короткий ответ - к сожалению, как и большинство других вещей, - это то, что зависит от обстоятельств. Различные страницы аутентификации по-разному обрабатывают запросы аутентификации, и поэтому вам, возможно, придется делать разные вещи для аутентификации по указанной c веб-службе.

На основе вашего кода

Я собираюсь сделать некоторые предположения, что страница входа, вероятно, ищет запрос POST с данными аутентификации (например, учетными данными) в форме объекта JSON на основе вашего кода и на основе ответа от сервера ошибка 406 означает, что вы отправляете данные с заголовком accept, который не совпадает с тем, как сервер хочет ответить.

При использовании запросов использование параметра data в запросе функция отправит данные "сырые"; то есть он отправит его в собственном формате данных (например, в случае двоичных данных) или переведет его в стандартные данные формы HTML, если этот формат не работает (например, key1=value1&key2=value2&key3=value3, эта форма имеет тип MIME application/x-www-form-urlencoded, и именно он будет отправлять запросы, если data не указан с заголовком accept). Я собираюсь сделать обоснованное предположение, основанное на том факте, что вы поместили свои учетные данные в словарь, что форма входа в систему ожидает POST-запрос с отформатированным телом JSON (большинство современных веб-приложений делают это), и вы были создается впечатление, что установка параметра data для запросов превратит его в объект 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)

Просмотрите этот раздел документации по запросам POST-запросов , если вы немного прокрутите оттуда, вы увидите, что в документации говорится о github API, который ожидает JSON, и о том, как с этим справиться.

В целом авторизация может быть сложной. Иногда может потребоваться "basi c auth", запросы которого будут ожидать, что вы передадите его как tuple в параметр auth, иногда им понадобится токен-носитель / OAUTH, который может вызвать головную боль. сложно / раздражает.

Надеюсь, это поможет!

0 голосов
/ 05 мая 2020

Вам не хватает пользовательского агента, который требуется серверу (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)
0 голосов
/ 05 мая 2020

Взгляните на Запросы: Basi c Аутентификация

import requests

requests.post(URL, auth=('user', 'pass'))

# If there are some cookies you need to send
cookies = dict(cookies_are='working')
requests.post(URL, auth=('user', 'pass'), cookies=cookies)
...