Хобрук: Ваш путь к мастерству в программировании

Очистка данных с помощью BeautifulSoup для каждой подстраницы - URL-адрес очень длинный и другой формат

Я собираю данные NFL о пасах за период с 1971 по 2019 год. Я смог очистить данные на первой странице каждого года, используя этот код:

# This code works:
passingData = []  # create empty list to store column data     
for year in range(1971,2020):
    url = 'https://www.nfl.com/stats/player-stats/category/passing/%s/REG/all/passingyards/desc' % (year)
    response = requests.get(url)
    response = response.content
    parsed_html = bsoup(response, 'html.parser')
    data_rows = parsed_html.find_all('tr')
    passingData.append([[col.text.strip() for col in row.find_all('td')] for row in data_rows])

На первой странице за каждый год есть только 25 игроков, и примерно 70-90 игроков каждый год выбрасывают пропуск (таким образом, в каждом году на подстраницах находится от 3 до 4 страниц данных об игроках). Проблема возникает, когда я пытаюсь очистить эти подстраницы. Я попытался добавить еще один подцикл, который извлекает href каждой ссылки на следующую страницу и добавляет к базовому URL-адресу, который находится в классе div 'nfl-o-table-pagination__buttons'. >

К сожалению, не могу добавить в список passData с первой страницы. Я попытался сделать следующее, но в строке subUrl произошла ошибка «Index Out of Range Error».

Я все еще новичок в парсинге веб-страниц, поэтому, если моя логика неверна, дайте мне знать. Я подумал, что могу просто добавить данные подстраницы (поскольку структура таблицы такая же), но, похоже, ошибка возникает, когда я пытаюсь перейти из:
https://www.nfl.com/stats/player-stats/category/passing/%s/REG/all/passingyards/desc
на вторую страницу, URL которой:
https://www.nfl.com/stats/player-stats/category/passing/2019/REG/all/passingYards/DESC?aftercursor=0000001900000000008500100079000840a7a000000000006e00000005000000045f74626c00000010706572736f6e5f7465616d5f737461740000000565736249640000000944415234363631343100000004726f6c6500000003504c5900000008736561736f6e496400000004323031390000000a736561736f6e5479706500000003524547f07fffffe6f07fffffe6389bd3f93412939a78c1e6950d620d060004

    for subPage in range(1971,2020):
        subPassingData = []
        subUrl = soup.select('.nfl-o-table-pagination__buttons a')[0]['href']
        new = requests.get(f"{url}{subUrl}")
        newResponse = new.content
        soup1 = bsoup(new.text, 'html.parser')
        sub_data_rows = soup1.find_all('tr')
        subPassingData.append([[col.text.strip() for col in row.find_all('td')] for row in data_rows])
        
    passingData.append(subPassingData)

Спасибо за помощь.


Ответы:


1

Этот скрипт работает со всеми выбранными годами и подстраницами и загружает данные в фрейм данных (или вместо этого вы можете сохранить их в csv и т. д.):

import requests
from bs4 import BeautifulSoup

url = 'https://www.nfl.com/stats/player-stats/category/passing/{year}/REG/all/passingyards/desc'
headers = {'User-Agent': 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:77.0) Gecko/20100101 Firefox/77.0'}

all_data = []

for year in range(2017, 2020):  # <-- change to desired year
    soup = BeautifulSoup(requests.get(url.format(year=year), headers=headers).content, 'html.parser')
    page = 1

    while True:
        print('Page {}/{}...'.format(page, year))

        for tr in soup.select('tr:has(td)'):
            tds = [year] + [td.get_text(strip=True) for td in tr.select('td')]
            all_data.append(tds)

        next_url = soup.select_one('.nfl-o-table-pagination__next')
        if not next_url:
            break

        u = 'https://www.nfl.com' + next_url['href']
        soup = BeautifulSoup(requests.get(u, headers=headers).content, 'html.parser')
        page += 1


# here we create dataframe from the list `all_data` and print it to screen:
from pandas import pd
df = pd.DataFrame(all_data)
print(df)

Отпечатки:

Page 1/2017...
Page 2/2017...
Page 3/2017...
Page 4/2017...
Page 1/2018...
Page 2/2018...
Page 3/2018...
Page 4/2018...
Page 1/2019...
Page 2/2019...
Page 3/2019...
Page 4/2019...
        0                   1     2    3    4    5      6   7   8      9   10     11  12  13  14  15   16
0    2017           Tom Brady  4577  7.9  581  385  0.663  32   8  102.8  230  0.396  62  10  64  35  201
1    2017       Philip Rivers  4515  7.9  575  360  0.626  28  10     96  216  0.376  61  12  75  18  120
2    2017    Matthew Stafford  4446  7.9  565  371  0.657  29  10   99.3  209   0.37  61  16  71  47  287
3    2017          Drew Brees  4334  8.1  536  386   0.72  23   8  103.9  201  0.375  72  11  54  20  145
4    2017  Ben Roethlisberger  4251  7.6  561  360  0.642  28  14   93.4  207  0.369  52  14  97  21  139
..    ...                 ...   ...  ...  ...  ...    ...  ..  ..    ...  ...    ...  ..  ..  ..  ..  ...
256  2019      Trevor Siemian     3  0.5    6    3    0.5   0   0   56.3    0      0   0   0   3   2   17
257  2019       Blake Bortles     3  1.5    2    1    0.5   0   0   56.3    0      0   0   0   3   0    0
258  2019       Kenjon Barner     3    3    1    1      1   0   0   79.2    0      0   0   0   3   0    0
259  2019         Alex Tanney     1    1    1    1      1   0   0   79.2    0      0   0   0   1   0    0
260  2019          Matt Haack     1    1    1    1      1   1   0  118.8    1      1   0   0   1   0    0

[261 rows x 17 columns]
29.06.2020
  • Идеальный! Он прошел успешно. Спасибо, что поместили его в pandas df, что значительно упрощает объединение заголовков и их сохранение. Большое спасибо! 30.06.2020
  • Новые материалы

    Я собираюсь научить вас Python шаг за шагом
    Привет, уважаемый энтузиаст Python! 👋 Готовы погрузиться в мир Python? Сегодня я приготовил для вас кое-что интересное, что сделает ваше путешествие более приятным, чем шарик мороженого в..

    Альтернатива шаблону исходящих сообщений для архитектуры микросервисов
    Познакомьтесь с двухэтапным сообщением В этой статье предлагается альтернативный шаблон для папки Исходящие : двухэтапное сообщение. Он основан не на очереди сообщений, а на..

    React on Rails
    Основное приложение Reverb - это всеми любимый монолит Rails. Он отлично обслуживает наш API и уровень просмотра трафика. По мере роста мы добавляли больше интерактивных элементов..

    Что такое гибкие методологии разработки программного обеспечения
    Что представляют собой гибкие методологии разработки программного обеспечения в 2023 году Agile-методологии разработки программного обеспечения заключаются в следующем: И. Введение A...

    Ториго  — революция в игре Го
    Наш следующий вызов против ИИ и для ИИ. Сможет ли он победить людей в обновленной игре Го? Обратите внимание, что в следующей статье AI означает искусственный интеллект, а Goban  —..

    Простое развертывание моделей с помощью Mlflow — Упаковка классификатора обзоров продуктов NLP от HuggingFace
    Как сохранить свои модели машинного обучения в формате с открытым исходным кодом с помощью MLFlow, чтобы позже получить возможность легкого развертывания. Сегодня модели упаковки имеют несколько..

    Математика и интуиция - Часть 1
    У каждой математической формулы есть доказательство. Часто эти доказательства слишком сложно понять, поскольку многие из них основаны на индукции, некоторые - на очень сложных наблюдениях, а..