2017-03-06 5 views
0

나는 www.whoscored.com에서 통계를 긁어 내고 판다 데이터 프레임을 작성하는 프로그램을 작성하려고 시도해 왔습니다.url이 변경되지 않을 때 Selenium을 사용하여 여러 페이지에 걸쳐 표를 긁음

나는 crookedleaf의 도움으로 코드를 업데이트하고이 작업 코드 :

import time 
import pandas as pd 
from pandas.io.html import read_html 
from pandas import DataFrame 
from selenium import webdriver 

driver = webdriver.Firefox() 
driver.get('https://www.whoscored.com/Regions/252/Tournaments/2/Seasons/6335/Stages/13796/PlayerStatistics/England-Premier-League-2016-2017') 

summary_stats = DataFrame() 

while True: 

    while driver.find_element_by_xpath('//*[@id="statistics-table-summary"]').get_attribute('class') == 'is-updating': # driver.find_element_by_xpath('//*[@id="statistics-table-summary-loading"]').get_attribute('style') == 'display; block;' or 
     time.sleep(1) 

    table = driver.find_element_by_xpath('//*[@id="statistics-table-summary"]') 
    table_html = table.get_attribute('innerHTML') 
    page_number = driver.find_element_by_xpath('//*[@id="currentPage"]').get_attribute('value') 
    print('Page ' + page_number) 
    df1 = read_html(table_html)[0] 
    summary_stats = pd.concat([summary_stats, df1]) 
    next_link = driver.find_element_by_xpath('//*[@id="next"]') 

    if 'disabled' in next_link.get_attribute('class'): 
     break 

    next_link.click() 

print(summary_stats) 

driver.close() 

가 지금은 다른 탭에서 통계를 수집하기 위해 노력하고 있습니다. 나는 정말 가깝지만 코드가 빠져 나가야 할 때 루프를 종료하지 않습니다. 여기에 아래의 코드입니다 :

defensive_button = driver.find_element_by_xpath('//*[@id="stage-top-player-stats-options"]/li[2]/a') 
defensive_button.click() 

defensive_stats = DataFrame() 

while True: 

    while driver.find_element_by_xpath('//*[@id="statistics-table-defensive"]').get_attribute('class') == 'is-updating': # driver.find_element_by_xpath('//*[@id="statistics-table-summary-loading"]').get_attribute('style') == 'display; block;' or 
     time.sleep(1) 

    table = driver.find_element_by_xpath('//*[@id="statistics-table-defensive"]') 
    table_html = table.get_attribute('innerHTML') 
    page_number = driver.find_element_by_xpath('//*[@id="statistics-paging-defensive"]/div/input[1]').get_attribute('value') 
    print('Page ' + page_number) 
    df2 = read_html(table_html)[0] 
    defensive_stats = pd.concat([defensive_stats, df2]) 
    next_link = driver.find_element_by_xpath('//*[@id="statistics-paging-defensive"]/div/dl[2]/dd[3]') 

    if 'disabled' in next_link.get_attribute('class'): 
     break 

    next_link.click() 

print(defensive_stats) 

이 코드는 모든 페이지를 통해 루프는, 그러나 당신은 당신의 루프 외부에서 테이블의 코드를 정의하는 마지막 페이지

답변

0

통해 반복 유지합니다. 다음 페이지로 이동하지만 tabletable_html 요소를 재정의하지 않았습니다. while True

EDIT : 코드를 변경 한 후 동적으로로드 된 내용이 테이블의 동적로드로 인해 발생했거나 변경 내용을 처리 할 수 ​​없거나 컨텐츠를 가져올 수 없습니다. "로드 중"그래픽 오버레이로 이동합니다. 또 다른 한 가지는 항상 30 페이지가 아닐 수도 있습니다. 예를 들어, 29가 있기 때문에 29 페이지의 데이터를 계속 가져옵니다. "next"버튼이 더 이상 활성화되지 않을 때까지 계속 실행되도록 코드를 수정했으며 테이블을 확인하기 위해 기다립니다 계속하기 전에로드 :

import time 
from pandas.io.html import read_html 
from pandas import DataFrame 
from selenium import webdriver 

driver = webdriver.Chrome(path-to-your-chromedriver) 
driver.get('https://www.whoscored.com/Regions/252/Tournaments/2/Seasons/6335/Stages/13796/PlayerStatistics/England-Premier-League-2016-2017') 

df = DataFrame() 

while True: 

    while driver.find_element_by_xpath('//*[@id="statistics-table-summary"]').get_attribute('class') == 'is-updating': # driver.find_element_by_xpath('//*[@id="statistics-table-summary-loading"]').get_attribute('style') == 'display; block;' or 
     time.sleep(1) 

    table = driver.find_element_by_xpath('//*[@id="statistics-table-summary"]') 
    table_html = table.get_attribute('innerHTML') 
    page_number = driver.find_element_by_xpath('//*[@id="currentPage"]').get_attribute('value') 
    print('Page ' + page_number) 
    df1 = read_html(table_html)[0] 
    df.append(df1) 
    next_link = driver.find_element_by_xpath('//*[@id="next"]') 

    if 'disabled' in next_link.get_attribute('class'): 
     break 

    next_link.click() 


print(df) 

driver.close() 

을하지만, 나는이 실행의 끝에서 빈 DataFrame을 얻고있다. 불행하게도이 문제를 확인하기 위해 pandas으로 익숙하지는 않지만 df.append()과 관련됩니다. 각 루프에서 df1의 값을 인쇄하여이를 실행하고 올바른 데이터를 인쇄하지만 DataFrame에 추가하지는 않습니다. 이는 완전히 실행하기 위해 필요한 변경 사항을 구현하기에 익숙한 것일 수 있습니다.

편집 2 :이 하나를 알아내는 데 시간이 오래 걸렸습니다. 기본적으로 페이지의 콘텐츠는 자바 스크립트로 동적으로로드됩니다. 선언하고있는 '다음'요소는 여전히 첫 번째 '다음'버튼입니다. 새 탭을 클릭 할 때마다 '다음'요소의 양이 증가합니다. 나는 성공적으로 모든 탭 ('자세한'탭 제외 ...)을 가로 질러 탐색하는 편집에서 추가했습니다 ... 잘하면이 하나의 롤이 필요하지 않습니다. 그러나 여전히 비어 있습니다. DataFrame()

import time 
import pandas as pd 
from pandas.io.html import read_html 
from pandas import DataFrame 
from selenium import webdriver 

driver = webdriver.Chrome('/home/mdrouin/Downloads/chromedriver') 
driver.get('https://www.whoscored.com/Regions/252/Tournaments/2/Seasons/6335/Stages/13796/PlayerStatistics/England-Premier-League-2016-2017') 

statistics = { # this is a list of all the tabs on the page 
    'summary': DataFrame(), 
    'defensive': DataFrame(), 
    'offensive': DataFrame(), 
    'passing': DataFrame() 
} 

count = 0 
tabs = driver.find_element_by_xpath('//*[@id="stage-top-player-stats-options"]').find_elements_by_tag_name('li') # this pulls all the tab elements 
for tab in tabs[:-1]: # iterate over the different tab sections 
    section = tab.text.lower() 
    driver.find_element_by_xpath('//*[@id="stage-top-player-stats-options"]').find_element_by_link_text(section.title()).click() # clicks the actual tab by using the dictionary's key (.proper() makes the first character in the string uppercase) 
    time.sleep(3) 
    while True: 
     while driver.find_element_by_xpath('//*[@id="statistics-table-%s"]' % section).get_attribute('class') == 'is-updating': # string formatting on the xpath to change for each section that is iterated over 
      time.sleep(1) 

     table = driver.find_element_by_xpath('//*[@id="statistics-table-%s"]' % section) # string formatting on the xpath to change for each section that is iterated over 
     table_html = table.get_attribute('innerHTML') 
     df = read_html(table_html)[0] 
     # print df 
     pd.concat([statistics[section], df]) 
     next_link = driver.find_elements_by_xpath('//*[@id="next"]')[count] # makes sure it's selecting the correct index of 'next' items 
     if 'disabled' in next_link.get_attribute('class'): 
      break 
     time.sleep(5) 
     next_link.click() 
    count += 1 


for df in statistics.values(): # iterates over the DataFrame() elemnts 
    print df 

driver.quit() 
+0

코드를 업데이트했지만 여전히 문제가 있습니다. 만약 당신이 다른 모습을 보니 정말 고마워 할 것입니다. – jchadwick92

+0

@ jchadwick92 제 답변에 대한 내 업데이트를 확인하고, 문제가 있다면 알려주세요 – crookedleaf

+0

코드가 훌륭하게 작동했습니다. 정말 고마워요. 나는 이제 방어 구역으로 넘어 갔지만 루프를 빠져 나가는 데 문제가 있습니다. 다시 볼 수 있습니까? – jchadwick92