Python Веб-сканирование с использованием Selenium и gChrome - PullRequest
0 голосов
/ 05 мая 2020

Я пытаюсь создать веб-страницу, но не могу найти элементы по имени их класса. Я вижу имя класса элемента на панели элементов Chrome, и при вводе его, как показано ниже, он возвращает пустой результат.

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

Я пытаюсь использовать эту таблицу лидеров page , чтобы очистить хотя бы имя пользователя и их баллы, дальнейший план состоит в том, чтобы также отметить их позицию и ввести ее в электронную таблицу Excel, но это в будущем, а не то, с чем у меня проблемы сейчас.

Результат, который я вижу при запуске 'usernames', - '[]', что, как я знаю, означает, что он пуст, но я не могу понять, почему, если я вижу элемент и его имя класса, и оно точно такое же. Должно быть, чего-то не хватает или я чего-то не знаю.

Ответы [ 3 ]

2 голосов
/ 05 мая 2020

РЕДАКТИРОВАТЬ: go вниз, чтобы увидеть ПУТЬ лучше, чтобы получить данные, не нужно извлекать из html в этом случае

Все работает! Просто нужно было подождать 10 секунд и искать только одно имя класса:

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)

Вывод:

['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']

Если вы хотите получить данные из других столбцов в таблице, то есть тоже возможно

РЕДАКТИРОВАТЬ:

Еще лучше, я смог получить веб-запрос XHR для возврата списка самых популярных зрителей (отсюда данные в таблице и находятся в json формат): https://api.streamelements.com/kappa/v2/points/5cf5740dc3334beee6ba64a6/top

Вы можете запросить это и получить данные намного быстрее без необходимости очистки, дайте мне знать, и я могу показать, как.

РЕДАКТИРОВАТЬ:

Хорошо, супер просто и WAAAAAAY лучше:

Требуется первая установка:

pip install requests

Затем:

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)

Вывод:

{'_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}]}

РЕДАКТИРОВАТЬ (снова):

Вот как получить его в excel (код немного изменился по сравнению с приведенным выше):

Сначала установите openpyxl:

pip install openpyxl

Затем запускаем скрипт:

import json
import requests
import openpyxl as xl


url = 'https://api.streamelements.com/kappa/v2/points/5cf5740dc3334beee6ba64a6/top'

# get a dictionary of the request's json response
response = requests.get(url).json()

# get just the user list
users = response['users']

# add the index + 1 as rank (because index starts at 0)
for user in users:
    user['rank'] = users.index(user) + 1

# create the workbook
wb = xl.Workbook()

# go to the active sheet
ws = wb.active

# write the header row
ws.append(list(users[0].keys()))

# write the values for each row
for user in users:
    ws.append(list(user.values()))

# save the workbook
wb.save('./streamelements-kappa.xlsx')
0 голосов
/ 05 мая 2020

Это потому, что вы ищете элемент, который является частью нескольких классов, а именно md-cell и leaderboard-row. Чтобы исправить это, используйте xpath для поиска элементов, в которых элементы являются частью класса md-cell и класса leaderboard-row:

usernames = driver.find_elements_by_xpath("//*[contains(@class, 'md-cell') and contains(@class, 'leaderboard-row')]")

Не забудьте добавить спящий режим, если строка выполняется до полной загрузки страницы

0 голосов
/ 05 мая 2020

Вероятно, имя класса - это не «md-cell leaderboard-row», а «md-cell», что идет после пробела, это селектор или что-то в этом роде, что я, честно говоря, не очень понимаю, так как я знаю почти ничего о CSS.

Однако этот код должен работать почти нормально:

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()

В этом коде вы получаете все md-ячейки, и вы увидите список со всеми ячеек, вы также можете получить строки, используя «md-row» вместо «md-cells», и вы получите список, и каждый элемент представляет собой строку, содержащую номер, имя и точки. Попробуйте

Ps: после того, как у вас есть список, вы можете проверить, пуст ли элемент.

...