ko ko ko en en en ko ko cs zh ko ko ko ko ko ko ko ko en ko ko ko ko ko ko en ko ko ko ko ko ko ko en ko en ko ko ko ko ko ko ko ko ko ko ko ko ko ko ar ko ko ko ko ko ko ko ko ko ko ko ko en ko ko ko en ko ko ko ko ko ko ko ko ko ko ko ko ko ko ko ko ko ko ko ko ko ko ko ko ko ko ko ko ko ko ko ko ko ko ko ko ko ko ko ko ko ko ko ko ko ko ko ko ko ko ko ko ko ko ko ko ko ko ko ko ko ko ko ko ko ko ko ko ko ko ko ko ko ko ko ko ko ko ko fr ko ko ko ko fr ko ko ko en en ko en zh en en
파이썬 코딩 도장: 46.3 웹 페이지의 HTML을 가져와서 파일로 저장하기
◀ 46.2 주피터 노트북 사용하기46.4 데이터로 그래프 그리기 ▶︎
이제 기상청 웹 사이트에서 도시별 현재날씨 페이지의 HTML을 가져와보겠습니다. 웹 브라우저를 실행하고 다음 주소로 이동합니다.
▼ 그림 46-15 기상청 도시별 현재날씨
웹 페이지를 보면 도시별 기상 데이터가 나옵니다. 많은 데이터가 표시되지만 우리는 이 웹 페이지에서 지점, 기온(현재기온), 습도만 가져오겠습니다.
참고로 기상청 웹 사이트는 시간이 지나면 개편을 하므로 웹 페이지의 HTML 구조도 바뀌게 됩니다. 특히 파이썬 코딩 도장 책이 나온 뒤에 기상청 웹 사이트가 개편되었을 경우에는 책 내용대로 실습을 할 수 없게 됩니다. 따라서 이번 유닛에서는 원활한 실습을 위해 도시별 현재날씨 페이지를 복사해서 올려놓은 Bitbucket 주소를 사용하겠습니다.
그럼 웹 브라우저에서 다음 주소로 이동하고, F12를 눌러서 개발자 도구를 표시합니다(여기서는 크롬을 사용하겠습니다). 그리고 왼쪽 아래 커서 버튼을 클릭(Ctrl+Shift+C)한 뒤 현재날씨 표에서 지점을 클릭합니다.
▼ 그림 46-16 개발자 도구에서 지점 선택
참고 | 웹 페이지가 열리지 않는다면?
이제 지점에 해당하는 HTML 코드가 표시됩니다. 여기서 스크롤을 위쪽으로 조금 올린 뒤 <table class="table_develop3" 부분을 클릭합니다. 그러면 표 전체가 선택되는데 이 표가 우리가 가져올 부분입니다.
▼ 그림 46-17 개발자 도구에서 표 선택
가져올 HTML을 확인했으면 주피터 노트북에 프로젝트 폴더(C:\project)를 지정해서 실행합니다(여기서는 반드시 아나콘다의 python.exe를 사용해야 합니다. 기존 파이썬 인터프리터를 사용하면 안 됩니다).
주피터 노트북에서 새 노트북을 만든 뒤 코드 셀에 다음 내용을 입력합니다.
import requests                  # 웹 페이지의 HTML을 가져오는 모듈 from bs4 import BeautifulSoup    # HTML을 파싱하는 모듈   # 웹 페이지를 가져온 뒤 BeautifulSoup 객체로 만듦 response = requests.get('https://pythondojang.bitbucket.io/weather/observation/currentweather.html') soup = BeautifulSoup(response.content, 'html.parser')   table = soup.find('table', { 'class': 'table_develop3' })    #  을 찾음 data = []                            # 데이터를 저장할 리스트 생성 for tr in table.find_all('tr'):      # 모든   태그를 찾아서 반복(각 지점의 데이터를 가져옴)     tds = list(tr.find_all('td'))    # 모든   태그를 찾아서 리스트로 만듦                                      # (각 날씨 값을 리스트로 만듦)     for td in tds:                   #   태그 리스트 반복(각 날씨 값을 가져옴)         if td.find('a'):             #   안에   태그가 있으면(지점인지 확인)             point = td.find('a').text    #   태그 안에서 지점을 가져옴             temperature = tds[5].text    #   태그 리스트의 여섯 번째(인덱스 5)에서 기온을 가져옴             humidity = tds[9].text       #   태그 리스트의 열 번째(인덱스 9)에서 습도를 가져옴             data.append([point, temperature, humidity])    # data 리스트에 지점, 기온, 습도를 추가   data    # data 표시. 주피터 노트북에서는 print를 사용하지 않아도 변수의 값이 표시됨
실행을 해보면 Out [1]: 부분에 data의 값이 표시됩니다. 여기서 Out [1]:은 In [1]:의 출력이라는 뜻입니다.
▼ 그림 46-18 웹 페이지에서 가져온 데이터 표시
46.3.3  HTML의 데이터를 가져오는 방식 알아보기
그럼 지점, 기온(현재기온), 습도 값을 어떻게 가져오는지 알아보겠습니다. 웹 브라우저의 개발자 모드에서 왼쪽 아래 커서 버튼을 클릭(Ctrl+Shift+C)한 뒤 서울을 클릭합니다. 그러면 서울에 해당하는 태그들이 출력됩니다. 그다음에 서울의 현재기온 25.6과 습도 30도 클릭해봅니다. 이런 방식으로 HTML 코드와 웹 페이지 화면을 보면서 어떤 태그가 원하는 값인지 찾습니다.
▼ 그림 46-19 웹 페이지에서 원하는 값 찾기
이제 HTML 코드를 살펴보겠습니다.  에서 도시(지점)별 데이터는   태그로 묶여 있고, 세부 값은   태그에 들어있습니다. 여기서는   태그 안에   태그가 있으면 지점이라 판단하고, 지점 값을 가져옵니다. 그다음에 기온은 여섯 번째(인덱스 5)  의 값을 가져오고, 습도는 열 번째(인덱스 9)  의 값을 가져오면 됩니다.
...생략...                                서울                       맑음                                        18.9                      1                      1                      25.6                      6.7                      70                                                               30                      서남서                      2.1                      1010.1              ...생략...
다시 파이썬에서 HTML을 가져오는 부분입니다. 여기서는 requests 모듈로 웹 페이지의 HTML을 가져오고, bs4 모듈로 HTML을 파싱합니다(HTML 파싱은 텍스트 형태의 HTML 코드를 분석해서 객체로 만든 뒤 검색하거나 편집할 수 있도록 만드는 작업입니다. 그리고 bs4는 BeautifulSoup 라이브러리이고 HTML 코드를 파싱하는데 사용합니다).
import requests                  # 웹 페이지의 HTML을 가져오는 모듈 from bs4 import BeautifulSoup    # HTML을 파싱하는 모듈   # 웹 페이지를 가져온 뒤 BeautifulSoup 객체로 만듦 response = requests.get('https://pythondojang.bitbucket.io/weather/observation/currentweather.html') soup = BeautifulSoup(response.content, 'html.parser')
request.get에 URL을 넣으면 응답(Response) 객체가 나옵니다. 그리고 BeautifulSoup 클래스에 응답 객체의 content 속성과 'html.parser'를 넣습니다. content 속성에는 텍스트 형태의 HTML이 들어있으며, 파이썬의 html.parser 모듈을 사용해서 파싱하도록 설정합니다.
참고 | 아나콘다를 사용하지 않는다면?
requests와 bs4는 기본적으로 파이썬에 포함되어 있지 않습니다. 따라서 pip install requests, pip install bs4로 패키지를 설치해줍니다.
이제 BeautifulSoup 클래스로 만든 soup 객체로 태그를 찾습니다. 먼저 soup.find('table', { 'class': 'table_develop3' })과 같이 HTML의 class 속성(attribute)이 table_develop3인   태그를 찾습니다(HTML의 class는 태그의 스타일을 지정할 때 사용하는 속성이며 파이썬의 클래스와는 다릅니다).
table = soup.find('table', { 'class': 'table_develop3' })    #  을 찾음
그다음에는 데이터를 저장할 리스트 data를 만듭니다. 그리고 for tr in table.find_all('tr'):과 같이 table에서 모든   태그를 찾아서 반복합니다. 즉, 이   태그에 서울, 백령도, 인천 등 지점별 데이터가 들어있으므로 반복할 때마다 서울, 백령도, 인천 등 각 지점의 데이터를 가져옵니다.
data = []                            # 데이터를 저장할 리스트 생성 for tr in table.find_all('tr'):      # 모든   태그를 찾아서 반복(각 지점의 데이터를 가져옴)
각 지점의 데이터를 가져왔으면 list(tr.find_all('td'))과 같이 tr에서 모든   태그를 찾아서 리스트로 만듭니다. 이렇게 하면 지점, 현재일기, 시정, 운량, 중하운량, 현재기온, 이슬점온도, 불쾌지수, 일강수, 습도, 풍향, 풍속, 해면기압  가 리스트에 들어갑니다.
tds = list(tr.find_all('td'))    # 모든   태그를 찾아서 리스트로 만듦                                      # (각 날씨 값을 리스트로 만듦)
이제   태그 리스트 tds를 반복하면서 각 값을 가져옵니다. 먼저 if td.find('a'):와 같이 td에   태그가 있는지 확인합니다.   태그가 있으면 td.find('a').text와 같이   태그의 text속성에서 지점을 가져옵니다(text 속성은  텍스트 에서 태그 안에 들어있는 텍스트를 가져옵니다). 그리고 기온(현재기온)은 여섯 번째(인덱스 5), 습도는 열 번째(인덱스 9)에 있다는 것을 확인했으므로 tds[5].text에서 기온을 가져오고, tds[9].text에서 습도를 가져옵니다.
for td in tds:                   #   태그 리스트 반복(각 날씨 값을 가져옴)         if td.find('a'):             #   안에   태그가 있으면(지점인지 확인)             point = td.find('a').text    #   태그 안에서 지점을 가져옴             temperature = tds[5].text    #   태그 리스트의 여섯 번째(인덱스 5)에서 기온을 가져옴             humidity = tds[9].text       #   태그 리스트의 열 번째(인덱스 9)에서 습도를 가져옴             data.append([point, temperature, humidity])    # data 리스트에 지점, 기온, 습도를 추가
필요한 값을 가져왔으면 data 리스트 안에 [point, temperature, humidity]처럼 값을 리스트 형태로 추가해줍니다.
data.append([point, temperature, humidity])    # data 리스트에 지점, 기온, 습도를 추가
참고 | 웹 페이지 크롤링
지금까지 작성한 웹 페이지 크롤링 코드는 특정 태그가 있는지, 몇 번째에 위치한 태그를 가져온다든지 해서 생각보다 체계적이지 못한 느낌이 듭니다. 왜냐하면 우리가 가져오는 웹 페이지는 데이터를 화면에 보여주는게 목적일 뿐 데이터를 체계적으로 저장하는데는 적합하지 않기 때문입니다. 그래서 주어진 HTML 구성에 맞춰서 만들다 보니 코드가 깔끔하지 않습니다. 즉, 크롤링은 웹 페이지마다 전부 코드가 다르게 나오며 같은 웹 페이지라도 개편이 되면 크롤링 코드를 다시 만들어야 합니다.
46.3.4  데이터를 csv 파일에 저장하기
데이터가 완성되었으니 이 데이터를 파일에 저장해보겠습니다. 방금 data의 값을 출력한 뒤에 코드 셀이 하나 더 생겼을 겁니다. 이 코드 셀에서 다음 코드를 실행합니다(셸이 생기지 않았다면 메뉴의 Insert > Insert Cell Below 실행).
with open('weather.csv', 'w') as file:    # weather.csv 파일을 쓰기 모드로 열기     file.write('point,temperature,humidity\n')                  # 컬럼 이름 추가     for i in data:                                              # data를 반복하면서         file.write('{0},{1},{2}\n'.format(i[0], i[1], i[2]))    # 지점,온도,습도를 줄 단위로 저장
코드를 실행하면 프로젝트 폴더(C:\project)에 weather.csv 파일이 생성됩니다. csv 파일은 Comma-separated values의 약자인데 각 컬럼을 ,(콤마)로 구분해서 표현한다고 해서 csv라고 부릅니다. 여기서는 file.write('point,temperature,humidity\n')처럼 맨 윗줄에 컬럼 이름을 추가하고 그 다음 줄부터는 data를 반복하면서 file.write('{0},{1},{2}\n'.format(i[0], i[1], i[2]))와 같이 지점, 온도, 습도를 줄단위로 저장합니다. 이때 콤마와 값 사이에는 공백을 넣지 않고 반드시 붙여줍니다.
weather.csv 파일을 메모장이나 기타 텍스트 편집기로 열어보면 다음과 같은 모양으로 지점, 기온, 습도 값이 저장된 것을 볼 수 있습니다.
point,temperature,humidity 서울,25.6,30 백령도,18.4,62 인천,20.8,54 수원,25.0,41 ...생략...
특히 csv 파일을 저장할 때 컬럼 이름은 영어로 지정해줍니다. 영어로 지정하면 나중에 각 컬럼에 접근할 때 df.temperature처럼 속성으로 깔끔하게 사용할 수 있습니다.
◀ 46.2 주피터 노트북 사용하기46.4 데이터로 그래프 그리기 ▶︎
Unit 1. 소프트웨어 교육과 파이썬
Unit 2. 파이썬 설치하기
Unit 3. Hello, world!로 시작하기
Unit 4. 기본 문법 알아보기
Unit 5. 숫자 계산하기
Unit 6. 변수와 입력 사용하기
Unit 7. 출력 방법 알아보기
Unit 8. 불과 비교, 논리 연산자 알아보기
Unit 9. 문자열 사용하기
Unit 10. 리스트와 튜플 사용하기
Unit 11. 시퀀스 자료형 활용하기
Unit 12. 딕셔너리 사용하기
Unit 13. if 조건문으로 특정 조건일 때 코드 실행하기
Unit 14. else를 사용하여 두 방향으로 분기하기
Unit 15. elif를 사용하여 여러 방향으로 분기하기
Unit 16. for 반복문으로 Hello, world! 100번 출력하기
Unit 17. while 반복문으로 Hello, world! 100번 출력하기
Unit 18. break, continue로 반복문 제어하기
Unit 19. 계단식으로 별 출력하기
Unit 20. FizzBuzz 문제
Unit 21. 터틀 그래픽스로 그림 그리기
Unit 22. 리스트와 튜플 응용하기
Unit 23. 2차원 리스트 사용하기
Unit 24. 문자열 응용하기
Unit 25. 딕셔너리 응용하기
Unit 26. 세트 사용하기
Unit 27. 파일 사용하기
Unit 28. 회문 판별과 N-gram 만들기
Unit 29. 함수 사용하기
Unit 30. 함수에서 위치 인수와 키워드 인수 사용하기
Unit 31. 함수에서 재귀호출 사용하기
Unit 32. 람다 표현식 사용하기
Unit 33. 클로저 사용하기
Unit 34. 클래스 사용하기
Unit 35. 클래스 속성과 정적, 클래스 메서드 사용하기
Unit 36. 클래스 상속 사용하기
Unit 37. 두 점 사이의 거리 구하기
Unit 38. 예외 처리 사용하기
Unit 39. 이터레이터 사용하기
Unit 40. 제너레이터 사용하기
Unit 41. 코루틴 사용하기
Unit 42. 데코레이터 사용하기
Unit 43. 정규표현식 사용하기
Unit 44. 모듈과 패키지 사용하기
Unit 45. 모듈과 패키지 만들기
Unit 46. 실전예제: 웹의 데이터로 그래프 그리기
46.2 주피터 노트북 사용하기
46.3 웹 페이지의 HTML을 가져와서 파일로 저장하기
46.4 데이터로 그래프 그리기
C 언어 코딩 도장
- 이 사이트에 실린 모든 내용, 디자인, 이미지, 편집 구성의 저작권은 (주)도서출판 길벗과 지은이에게 있습니다.
- 저작권법에 의해 보호를 받는 저작물이므로 무단 전재와 복제를 금합니다.
- 책의 내용을 복제하여 블로그, 웹사이트 등에 게시할 수 없습니다.
- 링크, SNS 공유는 허용합니다.
서울시 마포구 서교동 월드컵로 10길 56 (서울시 마포구 서교동 467-9)
Copyright © 2016-2021 Coding Dojang