J'ai commencé un petit projet en créant ce qui est essentiellement une compilation indexée d'une pléthore de statistiques de la NFL avec une interface graphique simple et agréable. Heureusement, le site https://www.pro-football-reference.com a tous les des données que vous pouvez imaginer sous forme de tableaux qui peuvent être exportés au format CSV sur le site et copiés / collés manuellement. J'ai commencé à faire cela, puis à utiliser la bibliothèque Pandas, j'ai commencé à lire les CSV dans DataFrames pour utiliser les données.
Cela fonctionne très bien, cependant, récupérer manuellement toutes ces données est assez fastidieux, j'ai donc décidé d'essayer de créer un racleur Web qui peut extraire des tableaux HTML et les convertir en un format CSV utilisable. J'ai du mal, en particulier pour isoler les tables individuelles, mais aussi pour que le CSV produit soit rendu dans un format lisible / utilisable.
Voici à quoi ressemble le grattoir en ce moment:
table = soup.select_one('table.stats_table')
Cela envoie correctement la requête à l'URL, mais ne récupère pas les données que je recherche qui sont «Rushing_and_Receiving». Au lieu de cela, il récupère le premier tableau de la page «Statistiques et classement de l'équipe». Il rend également le CSV dans un format plutôt laid / pas utile comme celui-ci:
b'',b'',b'',b'Tot Yds & TO',b'',b'',b'Passing',b'Rushing',b'Penalties',b'',b'Average Drive',b'Player',b'PF',b'Yds',b'Ply',b'Y/P',b'TO',b'FL',b'1stD',b'Cmp',b'Att',b'Yds',b'TD',b'Int',b'NY/A',b'1stD',b'Att',b'Yds',b'TD',b'Y/A',b'1stD',b'Pen',b'Yds',b'1stPy',b'#Dr',b'Sc%',b'TO%',b'Start',b'Time',b'Plays',b'Yds',b'Pts',b'Team Stats',b'Opp. Stats',b'Lg Rank Offense',b'Lg Rank Defense' b'309',b'4944',b'920',b'5.4',b'22',b'8',b'268',b'288',b'474',b'3222',b'27',b'14',b'6.4',b'176',b'415',b'1722',b'8',b'4.1',b'78',b'81',b'636',b'14',b'170',b'30.6',b'12.9',b'Own 27.8',b'2:38',b'5.5',b'29.1',b'1.74' b'8',b'5',b'',b'',b'8',b'13',b'1',b'',b'12',b'12',b'13',b'5',b'13',b'',b'4',b'6',b'4',b'7',b'',b'',b'',b'',b'',b'1',b'21',b'2',b'3',b'2',b'5',b'4' b'8',b'10',b'',b'',b'20',b'20',b'7',b'',b'7',b'11',b'31',b'15',b'21',b'',b'11',b'15',b'4',b'15',b'',b'',b'',b'',b'',b'24',b'16',b'5',b'13',b'14',b'15',b'11'
Je sais que mon problème avec la récupération de la table correcte se trouve dans la ligne:
XXX
Je suis ce que je considérerais encore comme un novice en Python, donc si quelqu'un peut m'aider à être capable d'interroger et d'analyser une table spécifique avec BS4 au format CSV, je serais plus que reconnaissant! p>
Merci d'avance!
3 Réponses :
Je contournerais complètement la belle soupe puisque les pandas fonctionnent bien pour ce site. (au moins les 4 premiers tableaux que j'ai passés sous silence)
Documentation ici
Merci pour votre réponse! C'est ce que j'obtiens pour passer sous silence la documentation, bien sûr, il y a une méthode 'read_html' haha. Je vais vérifier cela et faire un rapport!
Cela a parfaitement fonctionné, je me sens comme un imbécile de manquer cela et de jouer avec BeautifulSoup pendant si longtemps. Au moins, j'ai eu un peu de science des données / analyse html 101. Mille mercis!
Ce site semble utiliser JS pour afficher certaines des tables - consultez requests_html
< / a> au cas où quelque chose comme ça serait nécessaire.
Je ne suis pas sûr que cela fonctionne en raison du problème ajax mentionné ci-dessus. Heureusement, le point de terminaison ajax fournit du HTML valide qui peut être analysé avec bs4.
Merci! J'examinerai cela également. J'espère pouvoir obtenir tout ce dont j'ai besoin via to_csv / read_html avec des pandas, mais j'installerai requests_html et jetterai un meilleur coup d'œil à la documentation que j'ai fait avec Pandas haha.
J'ai essayé les méthodes 'read_html' et to_csv dans les pandas et j'ai pu analyser les tables en csv de manière séquentielle au fur et à mesure qu'elles apparaissaient sur la page, bien que je n'en ai essayé que quelques-unes. Lorsque je le mets en œuvre et que je commence à compiler toutes les données, je vous signale tous les problèmes que je rencontre.
La solution pandas n'a pas fonctionné pour moi à cause de la charge ajax, mais vous pouvez voir dans la console l'URL à partir de laquelle chaque table est chargée et la demander directement. Dans ce cas, l'URL est: https://widgets.sports-reference.com/wg.fcgi?css=1&site=pfr&url=%2Fteams%2Fnwe%2F2008.htm&div=div_rushing_and_receiving
Vous pouvez ensuite obtenir la table directement en utilisant son id rushing_and_receiving
.
Cela semble fonctionner.
from bs4 import BeautifulSoup import requests import csv def table_Scrape(): url = 'https://widgets.sports-reference.com/wg.fcgi?css=1&site=pfr&url=%2Fteams%2Fnwe%2F2008.htm&div=div_rushing_and_receiving' req = requests.get(url) soup = BeautifulSoup(req.text, 'html.parser') table = soup.find('table', id='rushing_and_receiving') headers = [th.text for th in table.findAll("tr")[1]] body = table.find('tbody') with open("out.csv", "w", encoding='utf-8') as f: wr = csv.writer(f) wr.writerow(headers) for data_row in body.findAll("tr"): th = data_row.find('th') wr.writerow([th.text] + [td.text for td in data_row.findAll("td")]) table_Scrape()
Hahaha je jure que j'ai essayé de passer soup.find ces mêmes paramètres ('table', id = 'rushing_and_receiving') et j'ai obtenu une erreur de mot-clé inattendue ou quelque chose du genre. J'apprécie vraiment tous les retours des gars!
Ahh je vois ce que tu veux dire, ça ne saisit que quelques tables. Je vais jouer un peu plus avec ces deux solutions et voir ce que je propose et mettre à jour ici si nécessaire.
J'aimerais pouvoir créditer ces deux réponses comme étant correctes, car elles sont toutes deux utiles, mais hélas, la deuxième réponse utilisant BeautifulSoup est la meilleure réponse car elle permet d'isoler des tables spécifiques, alors que la nature de la manière Le site est structuré limite l'efficacité de la méthode «read_html» dans Pandas.
Merci à tous ceux qui ont répondu!