Python - Scrape tytuły filmów za pomocą Splash i BS4

Nov 14 2020

Próbuję stworzyć swój pierwszy skrypt w Pythonie. Używam Splash i BS4.

Postępowałem zgodnie z tym samouczkiem Johna Watsona Rooneya (ale z własnym celem): Jak zeskrobać strony internetowe JAVASCRIPT za pomocą Pythona

Moim celem jest zeskrobanie ankiety z tej strony: Najlepsze filmy 2020 roku

Oto mój problem: renderuje wiele razy te same tytuły, ale z maksymalnie 6 duplikatami na liście bez logicznej kolejności. Czasami renderuje mniej niż 100 linii, czasami więcej?

Czego chcę :

  • Zdobądź 100 tytułów na zamówienie
  • Wyeksportuj je w formacie .csv.

Oto mój kod:

import requests
import csv
from bs4 import BeautifulSoup

url = 'https://www.senscritique.com/top/resultats/Les_meilleurs_films_de_2020/2582670'

r = requests.get('http://localhost:8050/render.html',
                 params={'url': url, 'wait': 2})

soup = BeautifulSoup(r.text, 'html.parser')

podium = soup.find_all('li', class_="elpo-item")
podium_list = []

for titres in podium:
    for titles in soup.find_all('h2'):
        podium_list.append(titles.text)

for liste in podium_list:
    print(liste)

Pytania :

  • Jak mogę wyrzucić tylko 100 tytułów? Co przegapiłem?
  • Czy mój kod jest prawidłowy, jak mogę go zoptymalizować?
  • Czy Splash jest naprawdę dobry do mojego użytku, czy jest inna, łatwiejsza biblioteka do skrobania strony JS?

Jeśli chodzi o część .csv, spróbuję teraz samemu, ale jeśli masz jakieś wskazówki, oczywiście słyszę!

Dziękuję za pomoc.

Odpowiedzi

1 baduker Nov 14 2020 at 19:07

Strony są faktycznie ładowane dynamicznie, co najmniej kolejne 50 filmów, więc musisz wysłać żądanie do innego punktu końcowego.

Oto jak:

import requests
from bs4 import BeautifulSoup


headers = {
    "Referer": "https://www.senscritique.com/top/resultats/Les_meilleurs_films_de_2020/2582670",
    "User-Agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36",
    "X-Requested-With": "XMLHttpRequest",
}

titles = []
for page in range(1, 3):
    url = f"https://www.senscritique.com/sc2/top/resultats/2582670/page-{page}.ajax?limit=1000"
    soup = BeautifulSoup(requests.get(url, headers=headers).text, "html.parser").find_all("li", {"class": "elpo-item"})
    titles.extend(i.find("h2").getText(strip=True).replace("(2020)", "") for i in soup)

for title in titles:
    print(title)

Wynik:

1917
Jojo Rabbit
The Gentlemen
Uncut Gems
Tenet
Le Cas Richard Jewell
Dark Waters
En avant
Drunk
Les Filles du docteur March
Adieu les cons
Invisible Man
Play
Les Enfants du temps
L'Adieu
La Plateforme
Séjour dans les monts Fuchun
The King of Staten Island
Été 85
Birds of Prey (et la Fantabuleuse Histoire de Harley Quinn)
La Communion
and so on...

Nawiasem mówiąc, filmy są w porządku.