Не удается получить доступ к дочерним тегам HTML с помощью BeautifulSoup

#python #html #web-scraping #beautifulsoup

Вопрос:

Я пытаюсь получить доступ к метаданным статьи с веб-сайта CNN. Их раздел «главные новости» находится под тегом, который начинается так:

 <section class="zn zn-homepage1-zone-1....
 

Под этим разделом каждая статья находится внутри тега, который выглядит следующим образом:

 <article class="cd cd--card cd--article....
 

На аналогичных сайтах я могу получить доступ к «главным новостям» со следующим подходом:

 cnnUrl = "https://www.cnn.com"
cnnSoup = BeautifulSoup(requests.get(cnnUrl, headers=headers).content, "html.parser")

homepageZone1 = '[class*="zn zn-homepage1-zone-1"]'

for item in cnnSoup.select(homepageZone1):
 

…и цикл for предоставит мне доступ к дочерним тегам, где я смогу собрать необходимые мне данные. Как только я это сделаю item , я обычно могу сделать что-то подобное для текста заголовка главной статьи CNN (этот формат время от времени меняется).:

 headline = item.find('h2').get_text()
 

Где headline бы это было (по состоянию на данный момент):

Чашка Петри Для Страны

Однако в этом случае я получаю None тип для homepageZone1 тега. Я попытался вернуться в родительский раздел homepageZone1 :

 cnnEverything = '[class*="pg-no-rail pg-wrapper"]'

for item in cnnSoup.select(cnnEverything):
 

Item здесь приведены следующие дочерние теги, но ни у одного из этих тегов на самом деле нет детей, к которым я могу получить доступ:

 <div class="pg-no-rail pg-wrapper"><div class="pg__background__image_wrapper"></div><div class="l-container"></div><section class="zn--idx-0 zn-empty"> </section><section class="zn--idx-1 zn-empty"> </section><section class="zn--idx-2 zn-empty"> </section><section class="zn--idx-3 zn-empty"> </section><section class="zn--idx-4 zn-empty"> </section><section class="zn--idx-5 zn-empty"> </section><section class="zn--idx-6 zn-empty"> </section><section class="zn--idx-7 zn-empty"> </section><section class="zn--idx-8 zn-empty"> </section><section class="zn--idx-9 zn-empty"> </section><section class="zn--idx-10 zn-empty"> </section><div class="ad ad--epic ad--all t-dark"><div class="ad-ad_bnr_btf_02 ad-refresh-adbody" data-ad-id="ad_bnr_btf_02" id="ad_bnr_btf_02"></div></div></div>
 

Чего мне не хватает?

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

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

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

3. Вы уверены, что в возвращаемом HTML-файле есть элементы <select> с указанными классами? Я только что попробовал, и у меня ничего не получилось с классами zn*. Однако, если я попытаюсь (например) www.cnn.com/world Я действительно вижу эти занятия

4. @AndyKnight достаточно интересно, что это не так. Однако, если я просматриваю заголовок с помощью веб-инспектора своего браузера, я вижу этот класс. Почему это так?

Ответ №1:

Я думаю, что нужный вам HTML запрашивается в отдельном запросе, а затем используется Javascript для добавления его в основной HTML (вот почему вы его не видите).

Ниже показано, как запросить международную версию из HTML внутри возвращенного JSON:

 from bs4 import BeautifulSoup
import requests

# International version
r = requests.get("https://edition.cnn.com/data/ocs/section/index.html:intl_homepage1-zone-1/views/zones/common/zone-manager.izl")
json_data = r.json()
html = json_data['html'].replace(r'"', '"')
cnnSoup = BeautifulSoup(html, 'html.parser')

for heading in cnnSoup.find_all(['h2', 'h3']):
    print(heading.text)
 

Даю вам следующие заголовки:

 Kandahar falls to Taliban
Militants take control of Afghanistan's second-largest city during an unrelenting sweep of the country, weeks before US troops are due to complete withdrawal
LIVE: UK defense chief worried about potential return of al Qaeda
Video allegedly shows Taliban celebrating after Kandahar gain
Afghanistan's quick unraveling threatens to stain Biden's legacy
...
 

URL-адрес был найден путем просмотра запросов, сделанных браузером во время загрузки страницы.