Как парсить стартовый состав НБА?

Я новичок в парсинге веб-страниц и мог бы использовать некоторую помощь. Я хотел бы очистить стартовый состав НБА, команды и позиции игроков, используя Xpath. Я только начал с имен, потому что столкнулся с проблемой.

Вот мой код:

from urllib.request import urlopen
from lxml.html import fromstring 


url = "https://www.lineups.com/nba/lineups"

content = str(urlopen(url).read())
comment = content.replace("-->","").replace("<!--","")
tree = fromstring(comment)


for nba, bball_row in enumerate(tree.xpath('//tr[contains(@class,"t-content")]')):
    names = bball_row.xpath('.//span[@_ngcontent-c5="long-player-name"]/text()')[0]
    print(names)

Похоже, программа работает без ошибок, но имена не печатаются. Мы будем очень признательны за любые советы о том, как более эффективно анализировать использование Xpath. Я пытался возиться с помощником Xpath и Xpath Finder. Возможно, есть какие-то хитрости, облегчающие процесс. Заранее спасибо за ваше время и усилия!


person Able Archer    schedule 23.10.2018    source источник
comment
Данные, которые вы хотите очистить, вводятся через Javascript. Вы не можете очистить его так, как вы это делаете. Попробуйте посмотреть Селениум.   -  person aris    schedule 23.10.2018
comment
Спасибо @арис! Я изучу Selenium и обновлю свой код, если разберусь.   -  person Able Archer    schedule 23.10.2018


Ответы (1)


Требуемый контент находится внутри узла script, который выглядит как

<script nonce="STATE_TRANSFER_TOKEN">window['TRANSFER_STATE'] = {...}</script>

Вы можете попробовать сделать следующее, чтобы извлечь данные в виде простого словаря Python:

import re
import json
import requests

source = requests.get("https://www.lineups.com/nba/lineups").text
dictionary = json.loads(re.search(r"window\['TRANSFER_STATE'\]\s=\s(\{.*\})<\/script>", source).group(1))

Необязательно: вставьте выходные данные dictionary здесь и нажмите "Украсить", чтобы данные отображались в читаемом формате JSON

Затем вы можете получить доступ к требуемому значению по ключу, например.

for player in dictionary['https://api.lineups.com/nba/fetch/lineups/gateway']['data'][0]['home_players']:
    print(player['name'])

Kyrie Irving
Jaylen Brown
Jayson Tatum
Gordon Hayward
Al Horford

for player in dictionary['https://api.lineups.com/nba/fetch/lineups/gateway']['data'][0]['away_players']:
    print(player['name'])

D.J. Augustin
Evan Fournier
Jonathan Isaac
Aaron Gordon
Nikola Vucevic

Обновить

Наверное, я просто слишком усложнил :)

Это должно быть так же просто, как показано ниже:

import requests

source = requests.get("https://api.lineups.com/nba/fetch/lineups/gateway").json()
for player in source['data'][0]['away_players']:
        print(player['name'])

Обновление 2

Чтобы получить составы всех команд, используйте ниже:

import requests

source = requests.get("https://api.lineups.com/nba/fetch/lineups/gateway").json()

for team in source['data']:
    print("\n%s players\n" % team['home_route'].capitalize())
    for player in team['home_players']:
        print(player['name'])
    print("\n%s players\n" % team['away_route'].capitalize())
    for player in team['away_players']:
        print(player['name'])
person Andersson    schedule 23.10.2018
comment
Хорошо сделано. Как вы поняли, что ссылка на желаемый результат может быть внутри любого скрипта @sir Andersson? Есть ли какой-нибудь трюк, который нужно знать, используя инструменты разработчика? - person SIM; 23.10.2018
comment
@SIM, первое, что нужно попробовать, это просто скопировать часть необходимых данных -> открыть исходный код страницы (щелкнуть правой кнопкой мыши на странице-> Просмотреть исходный код страницы) -> Ctrl + F -> Ctrl + V. Если данных нет, то это, скорее всего, исходит от XHR. Но в данном случае данные находились в узле script в формате JSON и первый ключ JSON — это ссылка на API. Никакой магии :) - person Andersson; 23.10.2018
comment
Это сработало отлично, как рекламируется ... Большое спасибо @Andersson за вашу помощь. Потрясающая работа! знак равно - person Able Archer; 23.10.2018
comment
Я только что заметил, что не печатаются все команды и игроки. Сначала я подумал, что это из-за того, что все стартеры еще не были добавлены, но теперь стартеры обновлены. Я вижу 7 команд, напечатанных из приведенного выше кода, и лучшая команда не имеет названия. Любой совет @Andersson? Я очень благодарен за вашу помощь, сэр. - person Able Archer; 23.10.2018
comment
@AbleArcher, хм... У меня есть 6 стартовых команд для 3 текущих игр... Можете ли вы уточнить, что именно не так с выводом, поскольку я не уверен, какой результат вы хотите получить? Убедитесь, что вы используете код из второго блока обновления. - person Andersson; 23.10.2018
comment
На самом деле сегодня только 3 игры... Прошу прощения. Вывод правильный, как вы сказали. Все стартовые игроки и команды напечатаны. Однако похоже, что игроки 76er печатаются дважды. Я вижу Маркелла Фульца, напечатанную один раз на вершине и один раз под командой 76ers. В остальном он безупречен. Я очень благодарен вам за помощь, @Andersson! Большое спасибо за полученный опыт. знак равно - person Able Archer; 24.10.2018
comment
На самом деле этот код отлично работает благодаря @Andersson. Я считаю, что добавлял дополнительную строку кода. Еще раз спасибо всем, кто помог! - person Able Archer; 24.10.2018
comment
Обновление 2 работает как шарм. Проблема, с которой я столкнулся, заключалась в добавлении обновления 1 и обновления 2 вместе. Этот код именно то, что я искал. - person Able Archer; 24.10.2018
comment
Еще раз спасибо @Andersson! Можете ли вы помочь мне превратить этот код в кадр данных pandas? Я хотел бы иметь возможность импортировать эти данные в Excel. - person Able Archer; 29.10.2018
comment
@AbleArcher Извините, у меня мало опыта работы с Pandas ... Вы можете отправить новый тикет по этой проблеме и добавить тег pandas. Я уверен, что гуру Pandas поможет вам :) - person Andersson; 29.10.2018
comment
Спасибо, сэр @Andersson, за ваше время. Это было очень полезно. знак равно - person Able Archer; 29.10.2018
comment
Могу ли я как-нибудь связаться с вами для будущей работы @Andersson? Моя контактная информация есть в моем профиле. - person Able Archer; 12.11.2018
comment
@AbleArcher, если у вас есть какие-либо проблемы с кодированием, вы всегда можете опубликовать новый вопрос здесь, на SO. Я посмотрю, когда у меня будет время. Также есть много других пользователей, которые могут помочь. В настоящее время я работаю над проектом, поэтому не уверен, что у меня есть много времени для наставника. - person Andersson; 12.11.2018