Проблема в том, что внутри этого элемента <div class="a_b article_body | color_gray_dark" id="ctn_article_body">
есть сломанный или неполный тег <b>
. Взгляните на этот фрагмент кода со страницы html:
.
<div id="ctn_article_body" class="a_b article_body | color_gray_dark"><p class=""></b>La Asociación Ecologista de Defensa dela Naturaleza (AEDENAT) ha denunciado que las obras de la carretera que cruza la Universidad Complutense desde la carretera de La Coruña hasta Cuatro Caminos se están realizando "sin permisos de ningún tipo" y suponen "la destrucción de zonas de pinar en las cercanías del edificio de Filosofia B".</p>
Сразу после первых тегов <p></p>
следует тег </b>
без пары тегов <b>
. Это причина того, что "html.parser" не работает.
Используя этот текст,
from bs4 import BeautifulSoup
text = """<div id="ctn_article_body" class="a_b article_body | color_gray_dark"><p class=""></b>La Asociación Ecologista de Defensa de la Naturaleza (AEDENAT) ha denunciado que las obras de la carretera que cruza la Universidad Complutense desde la carretera de La Coruña hasta Cuatro Caminos se están realizando "sin permisos de ningún tipo" y suponen "la destrucción de zonas de pinar en las cercanías del edificio de Filosofia B".</p><div id="elpais_gpt-INTEXT" style="width: 0px; height: 0px; display: none;"></div><p class="">Por su parte, José Luis Garro, tercer teniente de alcalde, ha declarado a EL PAÍS: "Tenemos una autorización provisional del rector de la Universidad Complutense. Toda esa zona, además, está pendiente de un plan especial de reforma interior (PERI). Ésta es sólo una solución provisional".</p><p class="">Según Garro, el trazado de la carretera "ha tenido que dar varias vueltas para no tocar las masas arbóreas", aunque reconoce que se ha hecho "en algunos casos", si bien causando "un daño mínimo".</p><p class="footnote">* Este artículo apareció en la edición impresa del lunes, 22 de enero de 1990.</p></div>"""
soup = BeautifulSoup(text, "html.parser")
print(soup.find("div"))
Вывод:
<div class="a_b article_body | color_gray_dark" id="ctn_article_body"><p class=""></p></div>
Как решить эту проблему? Что ж, я сделал еще одну попытку с другим парсером, в этом случае я использовал "lxml" вместо "html.parser", и это сработало.
Он выбрал div, так что простое изменение этой строки должно сработать
soup = BeautifulSoup(text, "lxml")
Конечно, вам потребуется установить этот синтаксический анализатор.
РЕДАКТИРОВАТЬ:
Как прокомментировал ниже @moreni123, это решение кажется правильным для определенных случаев, но не для всех. Учитывая это, я добавлю еще один вариант, который также может работать.
Кажется, было бы лучше использовать Selenium для получения веб-страницы, учитывая, что некоторый контент был сгенерирован с помощью JavaScript и запросы не могут этого сделать, это не его цель.
Я собираюсь использовать Selenium с безголовым драйвером Chrome,
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from bs4 import BeautifulSoup
# article to fetch
url = "https://elpais.com/diario/1990/01/14/madrid/632319855_850215.html"
driver_options = Options()
driver_options.add_argument("--headless")
driver = webdriver.Chrome(executable_path="path/to/chrome/driver", options=driver_options)
# this is the source code with the js executed
driver.get(url)
page = driver.execute_script("return document.getElementsByTagName('html')[0].innerHTML")
# now, as before we use BeautifulSoup to parse it. Selenium is a
# powerful, tool you could use Selenium for this also
soup = BeautifulSoup(page, "html.parser")
print(soup.select("#ctn_article_body"))
#quiting driver
if driver is not None:
driver.quit()
Убедитесь, что путь к драйверу Chrome указан правильно, в этой строке
driver = webdriver.Chrome(executable_path="path/to/chrome/driver", options=driver_options)
Вот ссылка на Selenium doc и на ChromeDriver. Если вам нужно скачать его.
Это решение должно работать. По крайней мере, в этой статье, которую вы мне передали, это работает.
Уважаемый Gealber, большое спасибо за ваш ответ и помощь. Я уже протестировал ваше решение в нескольких статьях и могу признать, что оно работает. Однако я проверил структуру HTML как в веб-браузере, так и в красивом мыле и не нашел тега </b> (я использовал точно такую же статью, как и вы). После нескольких сотен статей я столкнулся с той же проблемой пустого тела, но и lxml, и html.parser не работают. Вот ссылка с примером: elpais.com/diario/1990/01/14/madrid/632319855_850215.html. У вас есть идея/решение на этот раз? Заранее спасибо!
Что касается той же статьи, давайте сначала разберемся,
</b>
будет виден только в том случае, если вы загрузите исходный код html. Исходный код html не совпадает с кодом, который показывает вам инспектор браузера, по крайней мере, не всегда. Чтобы увидеть этот исходный код, вы можете загрузить его с помощью запросов и сохранить в файле для последующего анализа или в Chrome, нажав Ctr+U. Теперь, на этой последней странице, которую вы мне передаете, прямо перед этим текстом `color_gray_dark"><p class=""></b>Un hombre de 59 años`. Попробуйте воспроизвести эти шаги и расскажите мне об этом.Если вы запутались, исходный код не тот, потому что инспектор в браузере показывает вам весь код после выполнения JavaScript, но это не то, что вы загружаете с помощью запросов. С запросом вы загружаете HTML без выполнения JavaScript. Есть возможность получить исходный код после выполнения JavaScript, но это с Selenium. Я тоже обновлю ответ с этой опцией