Не удается реплицировать AJAX с помощью запросов Python

#python #python-3.x #ajax #web-scraping #python-requests

#python #python-3.x #ajax #веб-очистка #python-запросы

Вопрос:

Я пытаюсь реплицировать ajax-запрос с веб-страницы (https://droughtmonitor.unl.edu/Data/DataTables.aspx ). AJAX инициируется, когда мы выбираем значения из выпадающих списков.

Я использую следующий запрос с использованием python, но не могу увидеть ответ, как на вкладке Сети браузера.

 import bs4
import requests
import lxml

ses = requests.Session()
ses.get('https://droughtmonitor.unl.edu/Data/DataTables.aspx')
headers_dict = {'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36'
    }
url = 'https://droughtmonitor.unl.edu/Ajax2018.aspx/ReturnTabularDMAreaPercent_urban'
req_data = {'area':'00064', 'statstype':'1'}
resp = ses.post(url,data = req_data,headers = headers_dict)
    
soup = bs4.BeautifulSoup(resp.content,'lxml')
print(soup)
 

Комментарии:

1. какова ваша переменная state ? Я не могу запустить ваш код, потому state что он не определен.

2. @wuerfelfreak обновлено

Ответ №1:

Вам нужно добавить несколько вещей к вашему запросу, чтобы получить ответ от сервера.

  1. Вам нужно преобразовать ваш dict to json , чтобы передать его как строку, а не как dict .
  2. Вам также необходимо указать тип request-data , установив заголовок запроса на Content-Type:application/json; charset=utf-8

с этими изменениями я смог запросить данные correkt.

 import bs4
import requests

ses = requests.Session()
ses.get('https://droughtmonitor.unl.edu/Data/DataTables.aspx')
headers_dict = {'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36',
                'Content-Type': 'application/json; charset=utf-8'}
url = 'https://droughtmonitor.unl.edu/Ajax2018.aspx/ReturnTabularDMAreaPercent_urban'
req_data = json.dumps({'area':'00037', 'statstype':'1'})
resp = ses.post(url,data = req_data,headers = headers_dict)
    
soup = bs4.BeautifulSoup(resp.content,'lxml')
print(soup)
 

Должен сказать, довольно сложная проблема.

Комментарии:

1. Нет необходимости пытаться превратить python dict в json с помощью кавычек. Запросы позаботятся об этом за вас, и если это не так, вам следует использовать json.dumps(pythondict).

2. О, да. Я забыл, что req_data это не является постоянным. Я добавил json.dumps , но оставил остальное без изменений, чтобы не нарушать ваш ответ. @EricTruett

Ответ №2:

Из документации по запросам:

Вместо того, чтобы кодировать dict самостоятельно, вы также можете передать его напрямую, используя параметр json (добавлен в версии 2.4.2), и он будет закодирован автоматически:

 >>> url = 'https://api.github.com/some/endpoint'
>>> payload = {'some': 'data'}
>>> r = requests.post(url, json=payload)
 

Затем, чтобы получить выходные данные, вызовите r.json() , и вы получите данные, которые ищете.