Почему BeautifulSoup возвращает повторяющиеся строки таблицы и вообще пропускает другие? - PullRequest
0 голосов
/ 18 апреля 2020

Я пытаюсь собрать статистику игроков MLB с сайта mlb.com, используя Selenium и BeautifulSoup, и возвращаю дубликаты многих игроков, а также скучаю по нескольким другим, просто проверив проверку зрения. Неясно, откуда берутся дубликаты или почему я скучаю по другим.

Я решил использовать Selenium вместо запросов, потому что данные хранятся в таблице, но не видны в HTML до тех пор, пока браузер загружает страницу. Есть идеи, откуда возникают ошибки целостности данных?

Заранее спасибо!

Основные моменты из моего сценария ниже

# Navigate to stats page
def getToStats():
    url = ("http://mlb.mlb.com/stats/sortable.jsp?c_id=mlb#elem=%5Bobject+Object%5D&tab_level=child&click_text=Sortable+Player+hitting&game_type='R'&season=2019&season_type=ANY&league_code='MLB'&sectionType=sp&statType=hitting&page=1&ts=1586832481387&playerType=ALL")
    driver.get(url)
    html = driver.page_source

# Get source HTML/CSS
def getCurrentURL():
    url = driver.current_url
    html = driver.page_source
    soup = BeautifulSoup(html, 'html.parser')
    new_soup = soup.find("tbody")
    return new_soup

def getPlayers(html):
    players = []
    for player in html.find_all('tr'):
        players.append(player)
    return players

def getPlayerStats(player):
    playerRecord = []
    for data in player.find_all('td'):
        stat = data.text.replace('\xa0','') # Removes empty non-ASCII character attached to player last name
        playerRecord.append(stat)
    playerRecord.pop(0) # Removes MLB determined player rank
    playerRecord.pop(2) # Removes empty non-ASCII element
    return playerRecord


##################FUNCTIONS COMPLETE CODE EXECUTION BEGINS######################
playerData = []
driver = webdriver.Chrome()
getToStats()
html = getCurrentURL()
players = getPlayers(html)
for player in players:
   playerData.append(getPlayerStats(player))

print('Page 1 retrieved')
pageNum = 2
for page in range(25):
    element = driver.find_elements_by_class_name('paginationWidget-next')
    driver.execute_script("arguments[0].click();", element[0])
    next_html = getCurrentURL()
    playerRecords = getPlayers(next_html)
    for player in playerRecords:
        playerData.append(getPlayerStats(player))
    print('Page ' + str(pageNum) + ' retrieved')
    pageNum = pageNum + 1
print('Found the data')

my_df = pd.DataFrame(playerData)
my_df.to_csv('mlb_stats_2019.csv', index = False, header = False)
print('Enjoy your CSV file')

Дублированный образец вывода

Ответы [ 2 ]

0 голосов
/ 19 апреля 2020

Оригинальный скрипт возвращал дубликаты одних значений и вообще пропускал другие, потому что он никогда не проходил мимо второй страницы таблицы. Он печатал каждого из первых 50 игроков (страница 1) дважды, а затем непрерывно перебирал каждого из 50 игроков на странице 2.

Я решил эту проблему с помощью оператора time.sleep (), чтобы браузер, чтобы фактически перейти к следующей странице, прежде чем пытаться очистить таблицу.

pageNum = 1
for player in players:
    playerData.append(getPlayerStats(player))
element = driver.find_elements_by_class_name('paginationWidget-next')
driver.execute_script("arguments[0].click();", element[0])
time.sleep(7)
print('Page 1 retrieved')

# Scrape data for pages 2-26 of the table
pageNum = 2
for page in range(25):
    next_html = getCurrentURL()
    playerRecords = getPlayers(next_html)
    for player in playerRecords:
        playerData.append(getPlayerStats(player))
    print('Page ' + str(pageNum) + ' retrieved')
    element = driver.find_elements_by_class_name('paginationWidget-next')
    driver.execute_script("arguments[0].click();", element[0])
    pageNum = pageNum + 1
    time.sleep(7)
print('Found the data - placing it in the database')
0 голосов
/ 18 апреля 2020

Попробуйте использовать инструмент разработчика Google Chrome (нажмите F12) и go перейдите на вкладку сети, обновите sh страницу. Вы можете найти, откуда эти данные: http://mlb.mlb.com/pubajax/wf/flow/stats.splayer?season=2019&sort_order=%27desc%27&sort_column=%27avg%27&stat_type=hitting&page_type=SortablePlayer&game_type=%27R%27&player_pool=ALL&season_type=ANY&sport_code=%27mlb%27&results=1000&recSP=1&recPP=50

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...