웹 스크래핑에 대해 배우고 다양한 케이스로 연습하고 있습니다. 웹 스크래핑을 위해 보통 뷰티풀숲(BeautifulSoup)이나 셀레니움(Selenium)과 같은 도구를 사용해 HTML 데이터를 파싱하고 필요한 정보를 추출했습니다. 이 방법들은 강력하지만, 때로는 코드가 복잡해지고, 웹 페이지의 구조 변화에 민감하게 반응할 수 있습니다.
그런데 수집하고자 하는 데이터가 웹 페이지에 표형식으로 정리되어 있다면 판다스 라이브러리의 read_html
함수를 사용해 훨씬 쉽고 간단하게 원하는 정보를 얻을 수 있습니다. HTML 테이블이 잘 구조화되어 있을 경우, 아주 간단하게 원하는 데이터를 얻을 수 있습니다.
read_html
은 판다스 라이브러리에서 제공하는 함수 중 하나로, HTML 파일이나 웹페이지에 있는 테이블 형태의 데이터를 쉽게 읽어올 수 있도록 도와줍니다. 이 함수는 내부적으로 HTML 테이블을 파싱하여 판다스의 DataFrame 객체로 변환합니다. 이를 통해 사용자는 복잡한 HTML 구조나 JavaScript 처리 없이도 웹 페이지의 데이터를 직접적으로 다룰 수 있게 됩니다.
read_html
의 사용법은 매우 간단합니다. 웹 페이지의 URL을 인자로 전달하면 해당 페이지 내의 모든 테이블 데이터를 DataFrame 형태로 반환합니다. 이러한 특성 덕분에 웹 스크래핑이 필요한 다양한 상황에서 read_html
을 유용하게 활용할 수 있습니다.
이번 포스팅에선 제가 즐겨보는 nba의 위키피디아 페이지에서 NBA 30개 팀 목록을 가져오는 예제를 통해 read_html
의 간단한 사용법을 정리해 보겠습니다.
위키피디아의 NBA 팀 목록 페이지를 사용하여, 판다스의 read_html
함수를 이용해 어떻게 쉽고 빠르게 웹 페이지에서 데이터를 수집할 수 있는지 살펴보겠습니다.
먼저, 필요한 판다스 라이브러리를 임포트합니다:
import pandas as pd
그 다음, NBA 팀 목록이 있는 위키피디아 페이지의 URL을 read_html
함수에 전달합니다. 이 함수는 페이지 내의 모든 테이블을 찾아 각각을 DataFrame 객체로 변환하여 리스트로 반환합니다:
url = 'https://ko.wikipedia.org/wiki/NBA'
tables = pd.read_html(url)
이제 원하는 테이블을 찾기 위해 read_html
의 match
파라미터를 활용할 수 있습니다. 예를 들어, 테이블에 '수용 인원'이라는 키워드가 있다면, 이 키워드를 사용하여 원하는 테이블을 쉽게 찾을 수 있습니다. 실제 코드 예시는 다음과 같습니다:
nba_tables = pd.read_html(url, match='수용 인원')
이 코드는 '수용 인원'이라는 단어를 포함하는 테이블만을 찾아서 반환합니다. 이렇게 필터링된 nba_tables
리스트는 원하는 데이터를 포함하는 테이블들만을 포함하게 됩니다. 대부분의 경우, 이 리스트는 하나 또는 소수의 테이블만을 포함할 것입니다.
df = nba_tables[0]
이 코드는 필터링된 첫 번째 테이블을 출력합니다.
디비전 | 구단명 | 연고지 | 경기장 | 수용 인원 | 창설 | 가맹 | Unnamed: 7_level_0 | |
---|---|---|---|---|---|---|---|---|
동부 콘퍼런스 | 동부 콘퍼런스 | 동부 콘퍼런스 | 동부 콘퍼런스 | 동부 콘퍼런스 | 동부 콘퍼런스 | 동부 콘퍼런스 | 동부 콘퍼런스 | |
0 | 애틀랜틱 | 보스턴 셀틱스 | 매사추세츠주 보스턴 | TD 가든 | 18,624명 | 1946년 | 1946년 | NaN |
1 | 애틀랜틱 | 브루클린 네츠 | 뉴욕주 브루클린 | 바클레이스 센터 | 17,732명 | 1967년 | 1976년 | NaN |
2 | 애틀랜틱 | 뉴욕 닉스 | 뉴욕주 뉴욕 | 매디슨 스퀘어 가든 | 19,033명 | 1946년 | 1946년 | NaN |
3 | 애틀랜틱 | 필라델피아 세븐티식서스 | 펜실베이니아주 필라델피아 | 웰스 파고 센터 | 20,328명 | 1946년 | 1949년 | NaN |
4 | 애틀랜틱 | 토론토 랩터스 | 온타리오주 토론토 | 스코샤뱅크 아레나 | 19,800명 | 1995년 | 1995년 | NaN |
5 | 센트럴 | 시카고 불스 | 일리노이주 시카고 | 유나이티드 센터 | 20,917명 | 1966년 | 1966년 | NaN |
6 | 센트럴 | 클리블랜드 캐벌리어스 | 오하이오주 클리블랜드 | 로키 모기지 필드하우스 | 20,562명 | 1970년 | 1970년 | NaN |
7 | 센트럴 | 디트로이트 피스턴스 | 미시간주 디트로이트 | 리틀시저스 아레나 | 21,000명 | 1941년 | 1948년 | NaN |
8 | 센트럴 | 인디애나 페이서스 | 인디애나주 인디애나폴리스 | 게인브리지 필드하우스 | 18,165명 | 1967년 | 1976년 | NaN |
9 | 센트럴 | 밀워키 벅스 | 위스콘신주 밀워키 | 파이서브 포럼 | 17,500명 | 1968년 | 1968년 | NaN |
10 | 사우스이스트 | 애틀랜타 호크스 | 조지아주 애틀랜타 | 스테이트팜 아레나 | 18,238명 | 1946년 | 1949년 | NaN |
11 | 사우스이스트 | 샬럿 호니츠 | 노스캐롤라이나주 샬럿 | 스펙트럼 센터 | 19,077명 | 1988년 | 1988년 | NaN |
12 | 사우스이스트 | 마이애미 히트 | 플로리다주 마이애미 | 카세야 센터 | 19,600명 | 1988년 | 1988년 | NaN |
13 | 사우스이스트 | 올랜도 매직 | 플로리다주 올랜도 | 암웨이 센터 | 18,846명 | 1989년 | 1989년 | NaN |
14 | 사우스이스트 | 워싱턴 위저즈 | 워싱턴 D.C. | 캐피털 원 아레나 | 20,308명 | 1961년 | 1961년 | NaN |
15 | 서부 콘퍼런스 | 서부 콘퍼런스 | 서부 콘퍼런스 | 서부 콘퍼런스 | 서부 콘퍼런스 | 서부 콘퍼런스 | 서부 콘퍼런스 | 서부 콘퍼런스 |
16 | 노스웨스트 | 덴버 너기츠 | 콜로라도주 덴버 | 볼 아레나 | 19,155명 | 1967년 | 1976년 | NaN |
17 | 노스웨스트 | 미네소타 팀버울브스 | 미네소타주 미니애폴리스 | 타깃 센터 | 19,356명 | 1989년 | 1989년 | NaN |
18 | 노스웨스트 | 오클라호마시티 선더 | 오클라호마주 오클라호마시티 | 페이콤 센터 | 18,203명 | 2008년 | 2008년 | NaN |
19 | 노스웨스트 | 포틀랜드 트레일블레이저스 | 오리건주 포틀랜드 | 모다 센터 | 20,636명 | 1970년 | 1970년 | NaN |
20 | 노스웨스트 | 유타 재즈 | 유타주 솔트레이크시티 | 델타 센터 | 19,911명 | 1974년 | 1974년 | NaN |
21 | 퍼시픽 | 골든스테이트 워리어스 | 캘리포니아주 샌프란시스코 | 체이스 센터 | 18,064명 | 1946년 | 1946년 | NaN |
22 | 퍼시픽 | 로스앤젤레스 클리퍼스 | 캘리포니아주 로스앤젤레스 | 크립토닷컴 아레나 | 19,060명 | 1970년 | 1970년 | NaN |
23 | 퍼시픽 | 로스앤젤레스 레이커스 | 캘리포니아주 로스앤젤레스 | 크립토닷컴 아레나 | 19,060명 | 1947년 | 1948년 | NaN |
24 | 퍼시픽 | 피닉스 선스 | 애리조나주 피닉스 | 풋프린트 센터 | 18,422명 | 1968년 | 1968년 | NaN |
25 | 퍼시픽 | 새크라멘토 킹스 | 캘리포니아주 새크라멘토 | 골든 1 센터 | 17,500명 | 1945년 | 1948년 | NaN |
26 | 사우스웨스트 | 댈러스 매버릭스 | 텍사스주 댈러스 | 아메리칸 에어라인스 센터 | 19,200명 | 1980년 | 1980년 | NaN |
27 | 사우스웨스트 | 휴스턴 로키츠 | 텍사스주 휴스턴 | 도요타 센터 | 18,023명 | 1967년 | 1967년 | NaN |
28 | 사우스웨스트 | 멤피스 그리즐리스 | 테네시주 멤피스 | 페덱스 포럼 | 18,119명 | 1995년 | 1995년 | NaN |
29 | 사우스웨스트 | 뉴올리언스 펠리컨스 | 루이지애나주 뉴올리언스 | 스무디킹 센터 | 17,188명 | 2002년 | 2002년 | NaN |
30 | 사우스웨스트 | 샌안토니오 스퍼스 | 텍사스주 샌안토니오 | 프로스트 뱅크 센터 | 18,581명 | 1967년 | 1976년 | NaN |
간단한 전처리를 해주도록 하겠습니다.
df.loc[:14, '구분'] = '동부 콘퍼런스'
df.loc[16:, '구분'] = '서부 콘퍼런스'
df.columns = df.columns.droplevel(1)
df.drop(columns='Unnamed: 7_level_0', inplace=True)
df.dropna(inplace=True)
df.reset_index(drop=True, inplace=True)
디비전 | 구단명 | 연고지 | 경기장 | 수용 인원 | 창설 | 가맹 | 구분 | |
---|---|---|---|---|---|---|---|---|
0 | 애틀랜틱 | 보스턴 셀틱스 | 매사추세츠주 보스턴 | TD 가든 | 18,624명 | 1946년 | 1946년 | 동부 콘퍼런스 |
1 | 애틀랜틱 | 브루클린 네츠 | 뉴욕주 브루클린 | 바클레이스 센터 | 17,732명 | 1967년 | 1976년 | 동부 콘퍼런스 |
2 | 애틀랜틱 | 뉴욕 닉스 | 뉴욕주 뉴욕 | 매디슨 스퀘어 가든 | 19,033명 | 1946년 | 1946년 | 동부 콘퍼런스 |
3 | 애틀랜틱 | 필라델피아 세븐티식서스 | 펜실베이니아주 필라델피아 | 웰스 파고 센터 | 20,328명 | 1946년 | 1949년 | 동부 콘퍼런스 |
4 | 애틀랜틱 | 토론토 랩터스 | 온타리오주 토론토 | 스코샤뱅크 아레나 | 19,800명 | 1995년 | 1995년 | 동부 콘퍼런스 |
5 | 센트럴 | 시카고 불스 | 일리노이주 시카고 | 유나이티드 센터 | 20,917명 | 1966년 | 1966년 | 동부 콘퍼런스 |
6 | 센트럴 | 클리블랜드 캐벌리어스 | 오하이오주 클리블랜드 | 로키 모기지 필드하우스 | 20,562명 | 1970년 | 1970년 | 동부 콘퍼런스 |
7 | 센트럴 | 디트로이트 피스턴스 | 미시간주 디트로이트 | 리틀시저스 아레나 | 21,000명 | 1941년 | 1948년 | 동부 콘퍼런스 |
8 | 센트럴 | 인디애나 페이서스 | 인디애나주 인디애나폴리스 | 게인브리지 필드하우스 | 18,165명 | 1967년 | 1976년 | 동부 콘퍼런스 |
9 | 센트럴 | 밀워키 벅스 | 위스콘신주 밀워키 | 파이서브 포럼 | 17,500명 | 1968년 | 1968년 | 동부 콘퍼런스 |
10 | 사우스이스트 | 애틀랜타 호크스 | 조지아주 애틀랜타 | 스테이트팜 아레나 | 18,238명 | 1946년 | 1949년 | 동부 콘퍼런스 |
11 | 사우스이스트 | 샬럿 호니츠 | 노스캐롤라이나주 샬럿 | 스펙트럼 센터 | 19,077명 | 1988년 | 1988년 | 동부 콘퍼런스 |
12 | 사우스이스트 | 마이애미 히트 | 플로리다주 마이애미 | 카세야 센터 | 19,600명 | 1988년 | 1988년 | 동부 콘퍼런스 |
13 | 사우스이스트 | 올랜도 매직 | 플로리다주 올랜도 | 암웨이 센터 | 18,846명 | 1989년 | 1989년 | 동부 콘퍼런스 |
14 | 사우스이스트 | 워싱턴 위저즈 | 워싱턴 D.C. | 캐피털 원 아레나 | 20,308명 | 1961년 | 1961년 | 동부 콘퍼런스 |
15 | 노스웨스트 | 덴버 너기츠 | 콜로라도주 덴버 | 볼 아레나 | 19,155명 | 1967년 | 1976년 | 서부 콘퍼런스 |
16 | 노스웨스트 | 미네소타 팀버울브스 | 미네소타주 미니애폴리스 | 타깃 센터 | 19,356명 | 1989년 | 1989년 | 서부 콘퍼런스 |
17 | 노스웨스트 | 오클라호마시티 선더 | 오클라호마주 오클라호마시티 | 페이콤 센터 | 18,203명 | 2008년 | 2008년 | 서부 콘퍼런스 |
18 | 노스웨스트 | 포틀랜드 트레일블레이저스 | 오리건주 포틀랜드 | 모다 센터 | 20,636명 | 1970년 | 1970년 | 서부 콘퍼런스 |
19 | 노스웨스트 | 유타 재즈 | 유타주 솔트레이크시티 | 델타 센터 | 19,911명 | 1974년 | 1974년 | 서부 콘퍼런스 |
20 | 퍼시픽 | 골든스테이트 워리어스 | 캘리포니아주 샌프란시스코 | 체이스 센터 | 18,064명 | 1946년 | 1946년 | 서부 콘퍼런스 |
21 | 퍼시픽 | 로스앤젤레스 클리퍼스 | 캘리포니아주 로스앤젤레스 | 크립토닷컴 아레나 | 19,060명 | 1970년 | 1970년 | 서부 콘퍼런스 |
22 | 퍼시픽 | 로스앤젤레스 레이커스 | 캘리포니아주 로스앤젤레스 | 크립토닷컴 아레나 | 19,060명 | 1947년 | 1948년 | 서부 콘퍼런스 |
23 | 퍼시픽 | 피닉스 선스 | 애리조나주 피닉스 | 풋프린트 센터 | 18,422명 | 1968년 | 1968년 | 서부 콘퍼런스 |
24 | 퍼시픽 | 새크라멘토 킹스 | 캘리포니아주 새크라멘토 | 골든 1 센터 | 17,500명 | 1945년 | 1948년 | 서부 콘퍼런스 |
25 | 사우스웨스트 | 댈러스 매버릭스 | 텍사스주 댈러스 | 아메리칸 에어라인스 센터 | 19,200명 | 1980년 | 1980년 | 서부 콘퍼런스 |
26 | 사우스웨스트 | 휴스턴 로키츠 | 텍사스주 휴스턴 | 도요타 센터 | 18,023명 | 1967년 | 1967년 | 서부 콘퍼런스 |
27 | 사우스웨스트 | 멤피스 그리즐리스 | 테네시주 멤피스 | 페덱스 포럼 | 18,119명 | 1995년 | 1995년 | 서부 콘퍼런스 |
28 | 사우스웨스트 | 뉴올리언스 펠리컨스 | 루이지애나주 뉴올리언스 | 스무디킹 센터 | 17,188명 | 2002년 | 2002년 | 서부 콘퍼런스 |
29 | 사우스웨스트 | 샌안토니오 스퍼스 | 텍사스주 샌안토니오 | 프로스트 뱅크 센터 | 18,581명 | 1967년 | 1976년 | 서부 콘퍼런스 |
셀레니움이나 뷰티풀숲을 사용했다면, tr태그를 하나씩 불러와서 td태그 안에 담긴 정보들을 리스트안에 담아서 데이터 프레임으로 변환하는 작업을 해야 했겠지만, read_html을 이용하면 이렇게 쉽게 데이터 프레임 형태로 데이터를 정리할 수 있습니다.
read_html
사용의 장점과 제약사항이번 섹션에서는 read_html
사용의 주요 장점과 제약사항을 살펴보겠습니다.
간결함과 편리성: read_html
을 사용하면 복잡한 HTML 구조나 JavaScript 처리 없이 웹 페이지의 테이블 데이터를 손쉽게 추출할 수 있습니다. 몇 줄의 코드로 필요한 데이터를 빠르게 수집할 수 있어 생산성이 높아집니다.
판다스의 기능 활용: 수집된 데이터는 판다스 데이터 프레임으로 반환되므로, 판다스가 제공하는 다양한 데이터 처리 및 분석 기능을 바로 사용할 수 있습니다.
테이블 데이터에 한정: read_html
은 HTML 테이블 데이터에 최적화되어 있습니다. 따라서, 테이블 형태가 아닌 데이터를 수집하는 데에는 한계가 있습니다.
동적 웹 페이지의 한계: JavaScript로 동적으로 생성되는 데이터는 read_html
로 직접 수집하기 어렵습니다. 이 경우, 셀레니움과 같은 도구를 별도로 사용해야 할 수 있습니다.