Bonjour, je souhaite obtenir des titres de films sur ce site Web :

enter image description here

url = "https://www.the-numbers.com/market/" + "2019" + "/top-grossing-movies"
raw = requests.get(url, headers={'User-Agent':'Mozilla/5.0'})  
html = BeautifulSoup(raw.text, "html.parser")
movie_list = html.select("#page_filling_chart > table > tbody > tr > td > b > a")
for i in range(len(movie_list)):
    print(movie_list[i].text)

J'ai reçu la réponse 200 et je n'ai aucun problème à explorer d'autres informations. mais le problème est dans la variable movie_list.

Lorsque j'imprime (movie_list), il renvoie juste une liste vide, ce qui signifie que j'utilise la balise de manière incorrecte.

1
data_minD 14 sept. 2020 à 16:20

3 réponses

Meilleure réponse

Si vous remplacez:

movie_list = html.select("#page_filling_chart > table > tbody > tr > td > b > a")

Avec:

movie_list = html.select("#page_filling_chart table tr > td > b > a")

Vous obtenez ce que je pense que vous cherchez. Le principal changement ici est le remplacement des sélecteurs enfants (parent > child) par des sélecteurs descendants (ancestor descendant), ce qui est beaucoup plus indulgent en ce qui concerne l'apparence du contenu intermédiaire.


Mise à jour: c'est intéressant. Votre choix de l'analyseur BeautifulSoup semble conduire à un comportement différent.

Comparer:

>>> html = BeautifulSoup(raw, 'html.parser')
>>> html.select('#page_filling_chart > table')
[]

Avec:

>>> html = BeautifulSoup(raw, 'lxml')
>>> html.select('#page_filling_chart > table')
[<table>
<tr><th>Rank</th><th>Movie</th><th>Release<br/>Date</th><th>Distributor</th><th>Genre</th><th>2019 Gross</th><th>Tickets Sold</th></tr>
<tr>
[...]

En fait, en utilisant l'analyseur lxml, vous pouvez presque utiliser votre sélecteur d'origine. Cela marche:

html.select("#page_filling_chart > table > tr > td > b > a"

Après analyse, un table n'a pas de tbody.

Après quelques essais, vous devrez réécrire votre requête d'origine comme ceci pour qu'elle fonctionne avec html.parser:

html.select("#page_filling_chart2 > p > p > p > p > p > table > tr > td > b > a")

Il semble que html.parser ne synthétise pas les éléments de fermeture </p> lorsqu'ils sont absents de la source, donc toutes les balises non fermées <p> aboutissent à une structure de document analysée bizarre.

5
larsks 15 sept. 2020 à 12:21

Cela devrait fonctionner:

url = 'https://www.the-numbers.com/market/2019/top-grossing-movies'
raw = requests.get(url)  
html = BeautifulSoup(raw.text, "html.parser")
movie_list = html.select("table > tr > td > b > a")
for i in range(len(movie_list)):
    print(movie_list[i].text)
2
Markus 14 sept. 2020 à 13:44

Voici la solution à cette question:

from bs4 import BeautifulSoup
import requests

url = "https://www.the-numbers.com/market/" + "2019" + "/top-grossing-movies"
raw = requests.get(url, headers={'User-Agent':'Mozilla/5.0'})  
html = BeautifulSoup(raw.text, "html.parser")
movie_table_rows = html.findAll("table")[0].findAll('tr')

movie_list = []
for tr in movie_table_rows[1:]:
    tds = tr.findAll('td')
    movie_list.append(tds[1].text) #Extract Movie Names

print(movie_list)

Fondamentalement, la façon dont vous essayez d'extraire le texte est incorrecte car les sélecteurs sont différents pour chaque balise d'ancrage de nom de film.

2
Dharman 14 sept. 2020 à 13:45