Невозможно очистить данные, которые не видны на экране, но являются частью слайдера / карусели - PullRequest
3 голосов
/ 30 октября 2019

Я не могу собрать данные на веб-сайте, который является частью слайдера / карусели. Когда я запускаю свой скрипт, он удаляет только первый элемент из слайдера / карусели. Он не просматривает все страницы внутри этой карусели.

Сайт, который я пытаюсь почистить:

www.yourstory.com

Мой сценарий Python:

soup = BeautifulSoup(response, 'html.parser')
divTag = soup.find_all("a", class_=['sc-VigVT', 'eJWBx'])

for tag in divTag:
    tdTags = tag.find_all("h3", class_=['sc-jAaTju', 'iNsSAY'])

    for tag in tdTags:
        print(tag.text)

Вывод:

Кунал Баль и Рохит Бансал раскрывают внутреннюю историю оборота Snapdeal

Есть 7 предметов карусели, но я могу получить только первый. Я не могу получить данные со 2-й по 7-ю страницы в карусели / ползунке.

Пожалуйста, проверьте изображение ниже, на что я имею в виду (красный кружок):

enter image description here

1 Ответ

3 голосов
/ 31 октября 2019

Карусель генерируется из Javascript с использованием данных JSON, жестко закодированных в JS. Точно, этот JSON представлен с:

window.__REDUX_STATE__= { ..... }

Итак, предположительно, к вашему сведению, этот сайт использует redux для управления состоянием приложения

Мы можем просто извлечь этот JSONс помощью следующего сценария:

import requests
from bs4 import BeautifulSoup
import json
import pprint

r = requests.get('https://yourstory.com/')

prefix = "window.__REDUX_STATE__="
soup = BeautifulSoup(r.content, "html.parser")

#get the redux state (json)
data = [
    json.loads(t.text[len(prefix):]) 
    for t in soup.find_all('script')
    if "__REDUX_STATE__" in t.text
]

#get only the section with cardType == "CarouselCard"
carouselCards = [
    t["data"]
    for t in data[0]["home"]["sections"]
    if ("cardType" in t) and (t["cardType"] == "CarouselCard")
][0]

#print all cards
pprint.pprint(carouselCards)

#get the name, image path & link path
print([
    (t["title"], t["path"], t["metadata"]["thumbnail"]) 
    for t in carouselCards
])

JSON имеет массив sections внутри поля home. Этот объект раздела содержит некоторый объект со значением cardType со значением CarouselCard, где есть данные, которые вы ищете

Кроме того, из JSON раздел карусели начинается следующим образом:

{
    "type":"content",
    "dataAPI":"/api/v2/featured_stories?brand=yourstory&key=CURATED_SET",
    "dataAttribute":"featured",
    "cardType":"CarouselCard",
    "data":[]
}

Итак, я полагаю, вы могли бы просто получить карты, используя API: https://yourstory.com/api/v2/featured_stories?brand=yourstory&key=CURATED_SET

import requests

r = requests.get('https://yourstory.com/api/v2/featured_stories?brand=yourstory&key=CURATED_SET')

#get the name, image path & link path
print([
    (t["title"], t["path"], t["metadata"]["thumbnail"]) 
    for t in r.json()["stories"]
])

, что более просто

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