В настоящее время я использую Python3 как способ изучить веб-сканирование и столкнулся с любопытной проблемой. Для контекста я пытаюсь очистить некоторые данные от https://www.cnn.com/ и получать различные заголовки новостей. Я использую библиотеки requests и BeautifulSoup.

В своих ответах я не получил ничего существенного. При отправке более простого запроса:

import requests
from bs4 import BeautifulSoup

response = requests.get('https://www.cnn.com/')
soup = BeautifulSoup(response.text, 'html.parser')
print(soup)

Я встретил кучу того, что похоже на CSS и несколько js. Только внизу я вижу div, в который, как я предполагаю, отрисовывается React. Проблема в том, что я не могу получить данные таким образом. Я думаю , что происходит то, что CNN заполняет эти данные, используя какие-то useEffect или componentDidMount, что означает, что они изначально не появятся в исходной DOM. Это, конечно, не вызывает беспокойства у пользователя-человека, но вызывает здесь некоторые проблемы.

Что я могу сделать, чтобы обойти эту проблему?

1
ac_nook 13 Июн 2020 в 05:01

1 ответ

Лучший ответ

В консоли разработчика Chrome, если вы проверите вкладку сети, вы увидите набор запросов, заканчивающихся на /zone-manager.izl:

Headline requests

Контент - это JSON с полем html, которое содержит некоторый HTML-контент (включая лечебные средства, которые мы ищем).

Контент организован в 4 зоны с 2 форматами URL. Вот пример кода, чтобы получить все это:

import requests

pageType1 = "_intl-homepage-zone-injection/index.html:intl_homepage-injection-zone"
pageType2 = "index.html:intl_homepage1-zone"

for i in range(1,5):
    r = requests.get(f"https://edition.cnn.com/data/ocs/section/{pageType1}-{i}/views/zones/common/zone-manager.izl")
    print(r.json()["html"])
    r = requests.get(f"https://edition.cnn.com/data/ocs/section/{pageType2}-{i}/views/zones/common/zone-manager.izl")
    print(r.json()["html"])

Похоже, URL-адрес заголовка:

https://edition.cnn.com/data/ocs/section/index.html:intl_homepage1-zone-1/views/zones/common/zone-manager.izl

Затем вы можете начать использовать или любой синтаксический анализатор HTML. для извлечения ваших данных.

Например, чтобы получить теги h2 и h3 (также известные как заголовки):

import requests
from bs4 import BeautifulSoup

r = requests.get("https://edition.cnn.com/data/ocs/section/index.html:intl_homepage1-zone-1/views/zones/common/zone-manager.izl")
soup = BeautifulSoup(r.text, 'html.parser')

print(soup.find("h2").text)
print([t.text for t in soup.findAll("h3")])

Выход :

Military leaders take a stand as Trump stays silent
['The US military -- which Trump often uses to bolster himself as a commander in chief -- is moving on from the President on racial inequality', 'Derek Chauvin eligible for $1M pension', 'Live Protests continue to grow across the US', "analysis Floyd protests have a plot twist I didn't see coming", "Fox News anchor calls out Trump for saying he's done more for African Americans than any president", 'What if the next Donald Trump is, well, Donald Trump?', "Cuomo: Proof of systemic racism is in Trump's Cabinet", "Videos raise question about in-custody death deemed an 'accident' by officials", 'Woman caught on video harassing Asian American exercising in park', 'The Tyrion Lannister lookalike dreaming of Bollywood stardom', 'New book about Melania Trump says she renegotiated her prenuptial agreement', 'Young Americans are having less sex', "Kareem Abdul-Jabbar's son arrested for allegedly stabbing neighbor", 'Outrage over single mother who died after waiting days for bus home during lockdown', 'Face masks are best way to reduce coronavirus transmission, study finds', 'Stunning images show how virus is overrunning hospitals', 'Achaeologist jailed for faking finds', 'Poland invaded Czech Republic last month, says it was just a misunderstanding']
1
Bertrand Martel 13 Июн 2020 в 02:41