J'essaie de Webscrape une page Web, mais trouver des éléments par leur nom de classe ne fonctionne pas. Je peux voir le nom de classe de l'élément dans le panneau Eléments de Chrome et en le saisissant, illustré ci-dessous, il renvoie un résultat vide.
from selenium import webdriver
chrome_path = r"C:\webdrivers\chromedriver.exe"
driver = webdriver.Chrome(chrome_path)
driver.get("https://streamelements.com/logna/leaderboard")
usernames = driver.find_elements_by_class_name("md-cell leaderboard-row")
usernames
J'essaie d'utiliser cette page de classement pour gratter au moins le nom d'utilisateur et leurs points, un autre plan est de noter également leur position et de la faire entrer dans une feuille de calcul Excel, mais c'est dans le futur et ce n'est pas ce avec quoi j'ai des problèmes pour le moment.
Le résultat que je vois en exécutant 'usernames' est '[]', ce que je sais signifie qu'il est vide mais je ne peux pas comprendre pourquoi si je peux voir l'élément et son nom de classe et c'est exactement la même chose. Il doit manquer quelque chose ou il y a quelque chose que je ne sais pas.
3 réponses
EDIT: allez en bas pour voir un meilleur moyen d'obtenir les données, il n'est pas nécessaire de les extraire du html dans ce cas
Ça marche! Il suffit d'attendre 10 secondes et de rechercher un seul nom de classe:
import time
from selenium import webdriver
chrome_path = r"C:\webdrivers\chromedriver.exe" # or wherever you have your chrome webdriver installed
driver = webdriver.Chrome(chrome_path)
driver.get("https://streamelements.com/logna/leaderboard")
# let the page load
time.sleep(10)
# list comprehension to return text of each element with class leaderboard-row
usernames = [element.text for element in
driver.find_elements_by_class_name("leaderboard-row")
if element.text != '']
print(usernames)
Production:
['underholderen', '42051', 'jimbyj', '39220', 'delynne', '35411', 'rawrnerunya', '30350', 'simmer5k', '25470', 'bloomspeed', '23885', 'jaidav2000', '22386', 'moobot', '18910', 'virgoproz', '18120', 'ottermandela', '18108', 'v_and_k', '17945', 'kalibxi', '17610', 'commanderroot', '17585', 'jujusan', '17575', 'mellowj', '15390', 'itsvodoo', '15080', 'lord_hal', '14945', 'darkk0ala', '14757', 'sirenmatty', '13230', 'myles_27', '12725', 'upsetpoptart', '12204', 'salsichasensuaal', '11535', 'artalartistic', '11519', 'shannonmcbe', '10895', 'winsock', '10850']
Si vous souhaitez obtenir des données à partir des autres colonnes du tableau, cela est également possible
ÉDITER:
Mieux encore, j'ai pu obtenir la requête Web XHR pour renvoyer la liste des principaux utilisateurs (c'est de là que proviennent les données du tableau et sont au format json): https://api.streamelements.com/kappa/v2/points/5cf5740dc3334beee6ba64a6/ haut
Vous pouvez interroger cela et obtenir les données beaucoup plus rapidement sans avoir à gratter, faites-le moi savoir et je peux vous montrer comment.
ÉDITER:
Ok, super simple et WAAAAAAY mieux:
Demandes de première installation:
pip install requests
Alors:
import json
import requests
url = 'https://api.streamelements.com/kappa/v2/points/5cf5740dc3334beee6ba64a6/top'
# get a dictionary of the request's json response
usernames = requests.get(url).json()
print(usernames)
Production:
{'_total': 19350, 'users': [{'username': 'underholderen', 'points': 42051}, {'username': 'jimbyj', 'points': 39220}, {'username': 'delynne', 'points': 35411}, {'username': 'rawrnerunya', 'points': 30350}, {'username': 'simmer5k', 'points': 25470}, {'username': 'bloomspeed', 'points': 23885}, {'username': 'jaidav2000', 'points': 22386}, {'username': 'moobot', 'points': 18910}, {'username': 'virgoproz', 'points': 18120}, {'username': 'ottermandela', 'points': 18108}, {'username': 'v_and_k', 'points': 17945}, {'username': 'kalibxi', 'points': 17610}, {'username': 'commanderroot', 'points': 17585}, {'username': 'jujusan', 'points': 17575}, {'username': 'mellowj', 'points': 15390}, {'username': 'itsvodoo', 'points': 15080}, {'username': 'lord_hal', 'points': 14945}, {'username': 'darkk0ala', 'points': 14757}, {'username': 'sirenmatty', 'points': 13230}, {'username': 'myles_27', 'points': 12725}, {'username': 'upsetpoptart', 'points': 12204}, {'username': 'salsichasensuaal', 'points': 11535}, {'username': 'artalartistic', 'points': 11519}, {'username': 'shannonmcbe', 'points': 10895}, {'username': 'winsock', 'points': 10850}, {'username': 'macklelotsmore', 'points': 10688}, {'username': 'kikyobooty', 'points': 10650}, {'username': 'jovikingdomkey', 'points': 10385}, {'username': 'dancerhands', 'points': 10186}, {'username': 'mapplerug45', 'points': 10185}, {'username': 'lurxx', 'points': 10175}, {'username': 'jellycat101', 'points': 9965}, {'username': 'dean_', 'points': 9880}, {'username': 'tagou_', 'points': 9550}, {'username': 'arthiphix', 'points': 9505}, {'username': 'beingred', 'points': 9307}, {'username': 'theemrmark', 'points': 9135}, {'username': 'tiptactoe', 'points': 8710}, {'username': 'aten', 'points': 8660}, {'username': 'sweegol', 'points': 8630}, {'username': 'taramichellee', 'points': 8625}, {'username': 'sindar44', 'points': 8590}, {'username': 'nitestalkrr', 'points': 8570}, {'username': 'swoapy', 'points': 8546}, {'username': 'logviewer', 'points': 8380}, {'username': 'umental', 'points': 8235}, {'username': 'chesterfield250', 'points': 8171}, {'username': 'theedgecution', 'points': 8152}, {'username': 'dreameater_gd', 'points': 8110}, {'username': 'camirios29', 'points': 7960}, {'username': 'dirty_soul', 'points': 7895}, {'username': 'princesschango', 'points': 7780}, {'username': 'tylerhunsicker', 'points': 7729}, {'username': 'toonybit', 'points': 7655}, {'username': 'angeloflight', 'points': 7515}, {'username': 'fentondy', 'points': 7325}, {'username': 'owgrandma', 'points': 7165}, {'username': 'ohitspb', 'points': 7150}, {'username': 'jayy557', 'points': 7140}, {'username': 'nightbot', 'points': 7125}, {'username': 'therealjt', 'points': 7110}, {'username': 'hawqks', 'points': 6970}, {'username': 'oxsaucy', 'points': 6930}, {'username': 'somoonm', 'points': 6910}, {'username': 'skiesti', 'points': 6890}, {'username': 'adeeduhs', 'points': 6695}, {'username': 'elmolovesdorothy', 'points': 6660}, {'username': 'liquigels', 'points': 6640}, {'username': 'shadowed21', 'points': 6630}, {'username': 'fakerwtd', 'points': 6450}, {'username': 'fragglefusion', 'points': 6440}, {'username': 'kickypip', 'points': 6230}, {'username': 'cerem5', 'points': 6230}, {'username': 'nikkigsus', 'points': 6225}, {'username': 'bigj808', 'points': 6135}, {'username': 'anotherttvviewer', 'points': 6070}, {'username': 'taratv', 'points': 6040}, {'username': 'l0nnix', 'points': 5970}, {'username': 'sainttt', 'points': 5965}, {'username': 'princejay__', 'points': 5905}, {'username': 'oniisammma', 'points': 5886}, {'username': 'marshallpawpatrol', 'points': 5839}, {'username': 'rosayallday', 'points': 5720}, {'username': 'garvsehgal98', 'points': 5700}, {'username': 'beethoven6', 'points': 5695}, {'username': 'nynxii', 'points': 5680}, {'username': 'tilly', 'points': 5672}, {'username': 'godgundam1019', 'points': 5615}, {'username': 'monoclekitteh', 'points': 5605}, {'username': 'steviewondaaa', 'points': 5580}, {'username': 'ianonymoose', 'points': 5545}, {'username': 'aris1535', 'points': 5477}, {'username': 'rimastino', 'points': 5445}, {'username': 'kodexow', 'points': 5395}, {'username': 'ssondara', 'points': 5360}, {'username': 'cyroku', 'points': 5325}, {'username': 'ankoubzh', 'points': 5250}, {'username': 'sajan_ow', 'points': 5205}, {'username': 'plucik7', 'points': 5125}, {'username': 'sutetchi_', 'points': 5108}]}
C'est parce que l'élément que vous recherchez est un élément qui fait partie de plusieurs classes, à savoir md-cell
et leaderboard-row
. Pour résoudre ce problème, utilisez xpath pour rechercher les éléments dans lesquels les éléments font partie de la classe md-cell
et de la classe leaderboard-row
:
usernames = driver.find_elements_by_xpath("//*[contains(@class, 'md-cell') and contains(@class, 'leaderboard-row')]")
Assurez-vous d'ajouter un sommeil si la ligne est exécutée avant que la page ne soit complètement chargée
Probablement le nom de la classe n'est pas "md-cell leaderboard-row" mais "md-cell" ce qui se passe après l'espace est un sélecteur ou quelque chose comme ça que je ne comprends vraiment pas vraiment, car je ne sais presque rien sur CSS .
Cependant, ce code devrait fonctionner presque correctement:
chrome_path = r"D:/PythonLessons/imageTest/chromedriver.exe"
driver = webdriver.Chrome(chrome_path)
driver.get("https://streamelements.com/logna/leaderboard")
usernames = driver.find_elements_by_class_name("md-cell")
for item in usernames:
print(item.text)
driver.close()
Dans ce code, vous obtenez toutes les md-cells et vous verrez une liste avec toutes les cellules, vous pouvez également obtenir les lignes en utilisant "md-row" au lieu de "md-cells" et vous obtiendrez une liste et chaque élément est une ligne contenant un nombre, un nom et des points. Essaie
Ps: vous pouvez vérifier après avoir obtenu la liste si l'élément est vide.
Questions connexes
Questions liées
De nouvelles questions
python
Python est un langage de programmation multi-paradigme, typé dynamiquement et polyvalent. Il est conçu pour être rapide à apprendre, comprendre, utiliser et appliquer une syntaxe propre et uniforme. Veuillez noter que Python 2 est officiellement hors support à partir du 01-01-2020. Néanmoins, pour les questions Python spécifiques à la version, ajoutez la balise [python-2.7] ou [python-3.x]. Lorsque vous utilisez une variante Python (par exemple, Jython, PyPy) ou une bibliothèque (par exemple, Pandas et NumPy), veuillez l'inclure dans les balises.