#javascript #python #html #web-scraping #dynamic-html
#javascript #python #HTML #вебскрапирование #dynamic-html
Вопрос:
Я пытаюсь выяснить, как очистить данные со следующего URL: https://www.aap.org/en-us/advocacy-and-policy/aap-health-initiatives/nicuverification/Pages/NICUSearch.aspx
Вот тип данных:
Похоже, что все заполняется из базы данных и загружается на веб-страницу с помощью javascript.
Я делал что-то подобное в прошлом, используя selenium
и PhantomJS
, но я не могу понять, как получить эти поля данных в Python.
Как и ожидалось, я не могу использовать pd.read_html
для решения проблем такого типа.
Возможно ли проанализировать результаты из:
from selenium import webdriver
url="https://www.aap.org/en-us/advocacy-and-policy/aap-health-initiatives/nicuverification/Pages/NICUSearch.aspx"
browser = webdriver.PhantomJS()
browser.get(url)
content = browser.page_source
Или, может быть, для доступа к фактическим базовым данным?
Если нет, то каковы другие подходы, кроме копирования и вставки в течение нескольких часов?
Редактировать:
Основываясь на приведенном ниже ответе, от @thenullptr я смог получить доступ к материалу, но только на странице 1. Как я могу адаптировать это для просмотра всех страниц [рекомендации по правильному анализу]? Моя конечная цель — иметь это в фрейме данных pandas
import requests
from bs4 import BeautifulSoup
r = requests.post(
url = 'https://search.aap.org/nicu/',
data = {'SearchCriteria.Level':'1', 'X-Requested-With':'XMLHttpRequest'},
) #key:value
html = r.text
# Parsing the HTML
soup = BeautifulSoup(html.split("</script>")[-1].strip(), "html")
div = soup.find("div", {"id": "main"})
div = soup.findAll("div", {"class":"blue-border panel list-group"})
def f(x):
ignore_fields = ['Collapse all','Expand all']
output = list(filter(bool, map(str.strip, x.text.split("n"))))
output = list(filter(lambda x: x not in ignore_fields, output))
return output
results = pd.Series(list(map(f, div))[0])
Комментарии:
1. Если вы используете webdriver, которым вы можете воспользоваться
browser.find_elements_by_class_name('yourClassName')
, и если вам нужно дождаться загрузки этих элементов, вы можете обойтисьWebDriverWait(browser,secondsToWaitFloat)
. Когда вы находите элементы по имени класса, вы получаете список элементов, к которым вы можете обратитьсяget_attribute('innerText')
, чтобы получить внутренний текст.2. Попробуйте использовать вкладку сеть в инструментах разработчика вашего браузера, чтобы просмотреть, какие вызовы XHR выполняются. Вероятно, существует общедоступный API, из которого страница получает информацию, которую вы можете извлечь.
3. @thenullptr есть несколько
XHR
объектов. Вот представление: i.imgur.com/BddXtgA.png Как я могу получить к ним доступ? Что бы я искал в частности (извините, я никогда раньше не использовал эти объекты).4. @libby Как бы вы порекомендовали найти классы? У меня есть
inspected
отдельные элементы, использующие Google Chrome. Я нашел<div class="col-md-7"><label>Email address: </label>emailaddresshere</div>
, например, чтобы получить адрес электронной почты. Будет ли вызываться класс, который я ищуcol-md-7
. Можете ли вы показать пример, как я мог бы извлечь эту информацию? Спасибо.5. @O.rka Я думаю, это может помочь: imgur.com/a/C4fJQhn Насколько я могу судить, страница ( search.aap.org/nicu ) принимает запрос POST для поиска, затем, как вы можете видеть на скриншоте, страница отвечает HTML-кодом, который вы можете увидеть на вкладке ответа.
Ответ №1:
Чтобы следовать моему последнему комментарию, приведенное ниже должно дать вам хорошую отправную точку. Просматривая вызовы XHR, вы просто хотите посмотреть, какие данные отправляются и принимаются от каждого из них, чтобы точно определить тот, который вам нужен. Ниже приведены необработанные данные POST, отправляемые в API при выполнении поиска, похоже, вам нужно использовать хотя бы один и включить последний.
{
"SearchCriteria.Name": "smith",
"SearchCriteria.City": "",
"SearchCriteria.State": "",
"SearchCriteria.Zip": "",
"SearchCriteria.Level": "",
"SearchCriteria.LevelAssigner": "",
"SearchCriteria.BedNumberRange": "",
"X-Requested-With": "XMLHttpRequest"
}
Вот простой пример того, как вы можете отправить post-запрос, используя библиотеку запросов, веб-страница ответит необработанными данными, чтобы вы могли использовать BS или аналогичный для их анализа, чтобы получить необходимую информацию.
import requests
r = requests.post('https://search.aap.org/nicu/',
data = {'SearchCriteria.Name':'smith', 'X-Requested-With':'XMLHttpRequest'}) #key:value
print(r.text)
С принтами <strong class="col-md-8 white-text">JOHN PETER SMITH HOSPITAL</strong>...
Комментарии:
1. Спасибо за это. Какую часть вы на самом деле используете
data
dictionary?2. данные — это просто параметр функции post, например.
r = requests.post('https://httpbin.org/post', data = {'key':'value'})
если это то, что вы имеете в виду3. о, я не знаю, как я этого не уловил. Вы рекомендуете какой-либо способ анализа
r.text
? Я подумал, что наиболее эффективный способ сделать это — начать сBedNumberRange
1, а затем двигаться вверх. Это HTML или выводимый Java-скрипт? Сначала я подумал, что это XML, и попытался использовать XML-деревья, но формат был отключен.4. Я пытаюсь использовать
BeautifulSoup
:soup = BeautifulSoup(html.split("</script>")[-1].strip(), "html") div = soup.find("div", {"id": "main"})
это лучший способ анализа результатов? Я не уверен, как использовать поиск по имени, поскольку я нашел имя, а затем искал, но не получил результатов. Хотя ваш пример smith работает отлично.5. Я также не понимаю, как получить доступ к разным номерам страниц