BeautifulSoup не извлекает все элементы

#python #web-scraping #beautifulsoup

#python #очистка веб-страниц #beautifulsoup

Вопрос:

Я пытаюсь извлечь информацию из http://www.emoryhealthcare.org/locations/offices/advanced-digestive-care-1.html .

Я хотел бы очистить специальности, которые отображаются в нижней трети страницы, а именно «Гастроэнтерология» и «Внутренняя медицина». Когда я проверяю элемент, я вижу, что это li of <div class="module bordered specialist"> , но когда я пытаюсь выполнить цикл по супу и распечатать каждый найденный элемент, возвращаются результаты, отличные от ожидаемых.

 <div class="module bordered specialist">
<ul>
<li>Cardiac Care</li>
<li>Transplantation</li>
<li>Cancer Care (Oncology)</li>
<li>Diagnostic Radiology</li>
<li>Neurosciences</li>
<li>Mental Health Services</li>
</ul>
</div>
  

Когда я открываю веб-сайт в браузере, я вижу, что вышеуказанные значения мигают перед переключением содержимого на ожидаемые результаты. Есть ли у меня способ повысить вероятность того, что я смогу очистить элементы, которые я намереваюсь?

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

1. Похоже, что на странице есть javascript, который изменяет содержимое после загрузки.

2. Вы могли бы использовать selenium и подождать несколько секунд (кажется, именно столько времени требуется для изменения)

Ответ №1:

Просто используйте selenium, чтобы подождать несколько секунд, затем выполните синтаксический анализ, как вы делали раньше. Похоже, это помогло.

 from selenium import webdriver
import os
import time
from bs4 import BeautifulSoup

chromedriver = "/Users/Rafael/chromedriver"
os.environ["webdriver.chrome.driver"] = chromedriver
driver = webdriver.Chrome(chromedriver)
driver.get('http://www.emoryhealthcare.org/locations/offices/advanced-digestive-care-1.html')
time.sleep(5)
html = driver.page_source

soup = BeautifulSoup(html, 'lxml')
results = soup.find_all("div", { "class" : "module bordered specialist" })
print(results[0].text) #prints GastroenterologyInternal Medicine
  

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

1. Ах, хорошо, значит, selenium и a time.sleep позволяют странице завершить загрузку перед синтаксическим анализом?

2. Да, это идея, есть более элегантные способы сделать это, ожидая загрузки определенного элемента, но этот сайт, похоже, достаточно последователен, чтобы это заняло всего несколько секунд

Ответ №2:

Вам не нужен selenium, простой post-запрос может получить данные:

введите описание изображения здесь

Итак, все, что вам нужно, это имитировать этот запрос:

 import requests

# you can change there fields to get different results
data = {"selectFields":["Name","URL","Specialists"],"filters":{},"orderBy":{"Name":-1}}

post = "http://www.emoryhealthcare.org/service/findPhysician/api/locations/retrieve"
 #  post the data as json and create a dict from the returned json.
js = requests.post(post, json=data).json()
print(js[u'locations'][0][u'Specialists'])
  

Что, если мы запустим его, даст вам:

 In [3]: import requests
...: 
...: data = {"selectFields":["Name","URL","Specialists"],"filters":{},"orderB
...: y":{"Name":-1}}
...: post =   "http://www.emoryhealthcare.org/service/findPhysician/api/locatio
...: ns/retrieve"
...: js = requests.post(post, json=data).json()
...: print(js[u'locations'][0][u'Specialists'])
...: 
[u'Gastroenterology', u'Internal Medicine']
  

В json содержится множество данных, там есть практически все, что вы, вероятно, захотите.