1 of 34

장고와 수프로 시작하는 웹 크롤링

장고걸스서울팀 / 이수진

sujinlee.me@gmail.com

www.sujinlee.me

2 of 34

자기소개

  • 웹을 좋아하다가 졸업 후 기획자로 커리어를 시작했지만….
  • 기획자+개발자 = 기발자 .. 인가요?
  • 친구들과 파이썬을 배우다 장고걸스서울을 시작했습니다.
  • 장고걸스튜토리얼 번역으로 장고에 입문했어요.
  • 생애 첫 개발 관련 발표입니다. :) 떨려욧 *_*

3 of 34

발표의 목적

  • 최근에 만든 마라톤 웹 크롤링 사이트를 만든 후기를 공유해요.
  • 비전공자 출신, 기획자도 코딩을 할 수 있다는 자신감을 드리고 싶어요.
  • 그래서 많은 분들이 개발자 흉내를 내보시길 바라요.
  • 장고걸스서울에서 더 많은 분들과 함께 하고 싶어요.

4 of 34

Hello, Ms.Python, 오늘 날씨는 어때요.

5 of 34

Hello, Ms.Python, 오늘 세미나 장소 �주소를 알려주세요.

6 of 34

여러분은 앞으로

  • BeautifulSoup4으로 웹사이트를 크롤링할 수 있어요. �(크롤링하기 전 웹사이트 저작권 정책을 꼭 살펴보세요)
  • Requests로 지도, 날씨 등등의 API 데이터를 추가할 수 있어요.
  • 파이썬으로 딕셔너리-리스트를 만들어 Django뷰로 연결시켜 그럴싸한 웹사이트를 만들 수 있어요.
  • Python 리스트를 Json로 변환하면 요즘 핫한 Firebase까지. 우후훗!�

7 of 34

웹 크롤링 사이트 

요런 90년대 올드한 느낌이 나는 웹사이트를 나이키st로 예쁘게 만들어봤어요.�http://www.sujinlee.me/runkorea/

8 of 34

Source

9 of 34

왜 만들었나요?

Coursera - Python for Everybody에서 �BeautifulSoup4, urllib2, 데이터 시각화 (구글 map 좌표 출력)를 배웠어요. (초보자에게 강추!)

http://pythonlearn.com/

지금까지 배운 내용을 응용해 장고로 웹사이트를 만들어보자!

→ 만들고 보니 장고 0.1티스푼정도  이해하게 되었어요.

10 of 34

어떤 것들을 추가했나요?

11 of 34

크롤링하기 전 선행 기본 지식

  • 문자열, 리스트, 딕셔너리를 자유자재로 다루고 원하는 값을 출력할 수 있습니다.
  • 하나의 함수에서 다른 함수를 호출할 수 있고, 함수를 다른 함수에 대한 인수로 사용할 수 있습니다.
  • Try, Except로 오류를 예측하고 다룰 수 있습니다.
  • 외부 파일을 읽고, 수정, 저장하고 새 파일을 생성해 데이터를 저장할 수 있습니다.
  • HTML 구조, 태그와 요소를 알고 있습니다.�
  • 파이썬 기초 책 한 권 정도 읽으면 할 수 있어요!

12 of 34

크롤링을 위한 도구

외부 패키지 - 설치가 필요합니다.$ pip install requestsHTTP 프로토콜과 헤더관련 사항을 처리해줘 파일처럼 웹페이지를 다룰 수가 있어요.�$ pip install beautifulsoup4HTML의 원소를 쉽게 추출하여 데이터를 얻을 수 있어요.

내부 패키지import re�정규표현식을 알면 문자열을 찾거나, 수정하거나, 원하는 형식 문자열으로 변경할 수 있어요.�import json딕셔녀리, 리스트를 json으로 변환할 수 있어요.

13 of 34

BeautifulSoup4

python3으로 웹 크롤링을 합니다.�

  • 야호, 한국어 문서가 있습니다.

14 of 34

왜 BeautifulSoup 수프일까요?

  1. ‘Tag Soup’ 란 마크업을 엉망진창으로(말아먹은;;) 만든 사람을 비아냥 거리는 단어로 쓰였습니다.
  2. 2004년까지는 완벽한 구조를 갖춘 XML, HTML문서만 파싱이 가능했습니다
  3. Beautiful Soup는 어떤 문서든지(broken structure) 쉽게 파싱이 가능해요!!
  4. 그리하여 Beautiful (대박!)하여,  Beautiful Soup이  되었습니다 :)

15 of 34

당신의 파싱을 소중하게, 한글 인코딩 문제 해결

  • python3를 쓰세요.
  • 파일(.py) 맨 앞에 꼭 #! -*- coding: utf8 -*-라고 적으세요.

  • 기본 인코딩 설정 값이 EUC-KR로 설정되어 있는 웹사이트의 경우, Socket 통신에서 utf-8로 encoding 변환해줘야 합니다. 

import requestsread=requests.get('URL')read.encoding = 'euc-kr'

# -*- coding: utf-8 -*-

16 of 34

웹사이트 구조 살펴보고  파싱하기

크롬 웹 브라우저에서 오른쪽버튼을 눌러 개발자 도구로 html 소스를 확인하세요.

import requestsfrom bs4 import BeautifulSoupread=requests.get('http://www.roadrun.co.kr/schedule/view.php?no=6198')read.encoding = 'euc-kr'soup = BeautifulSoup(read.content, 'html.parser')table = soup.find_all('table')[1]

print(table)

<table>

</table>

17 of 34

BeautifulSoup4 크롤링 간단 레시피

  • BeautifulSoup4으로 크롤링할 HTML원소를 찾고 이를 리스트로 만들기. (딕셔너리의 val값으로 활용될 거에요)
  • (옵션) Regex로 문자열 편집/가공하기
  • (옵션) 기타 API를 호출하여 값을 리스트에 추가하기
  • Key-Val(1번의 결과물)로 매칭하여 딕셔너리로 변환하기
  • 1~4과정을 반복(loop)하여, 딕셔너리 집합 리스트로 완성하기
  • (옵션) 1. json으로 만들기� 2. json sqlite로 DB 만들기 � 3. sqlite 로 DB 생성json로 변환하기.
  • 결과물을 파일로 만들기

[]

{}

�[{}, {}, {},.. {}]

18 of 34

  1. python 파일로 만들기

event_data.py

with open("event_data.py", "w") as f:try:f.write('# -*- coding: utf-8 -*-\nevent_dict={}'.format(str(all_data)))print("event_data.py Updated all data successfully!")except:print("event_data.py Error processing")

event_dict=[{'description': '경남에서 펼치지는 올해의 마지막 마라톤대회! 감사합니다.', 'location': '양산종합운동장', 'email': 'moon21@knnews.co.kr', 'weather': 'partly-cloudy-day', 'temperature': '6.68°C', 'website': 'http://www.ysrun.kr', 'date': '2016/12/04 09:30', 'race': '하프,10km,5km', 'city': '경남', 'application_period': '2016/5/30 - 2016/11/4', 'phone': '055-210-6103', 'host': '양산시, 경남신문', 'title': '제12회 양산전국하프마라톤', 'map_url': 'http:/…….

19 of 34

2. JSON 파일로 만들기

event_data.json

with open('event_data.json', 'w', encoding='utf8') as json_file:json_file.write(all_data)

[{"temperature": "0.81°C","longitude": "127.06892112991035","latitude": "37.52929744334148","location": "한강시민공원 뚝섬지구 수변무대","phone": "042-638-1080","website": "http://www.run1080.com/new/mini/index.php?code=841","weather": "partly-cloudy-day","map_url": "http://map.daum.net/link/map/11078317","email": "run0314@naver.com","race": ["풀","하프","10km","5km"],

20 of 34

  • XML(‘eXtensible Markup Language’)은 오랜 기간 사용되어져 왔고 문서-형식(document-style) 데이터를 교환하는데 가장 적합합니다. JSON(JavaScript Object Notation)은 .딕셔너리, 리스트 혹은 다른 내부 정보 교환을 위해 쓰입니다.�
  • JSON 형식은 자바스크립트 언어에서 사용되는 객체와 배열 형식에서 영감을 얻었습니다. 하지만 파이썬이 자바스크립트 이전에 개발되어서 딕셔너리와 리스트 의 파이썬 구문이 JSON 구문에 영향을 주었습니다. 그래서 JSON 포맷이 거의 파이 썬 리스트와 딕셔너리의 조합과 일치합니다�
  • 일반적으로 JSON 구조가 XML 보다 간단합니다. JSON 이 딕셔너리와 리스트의 조합에 직접 매핑된다는 장점이 있습니다. 그리고, 거의 모든 프로그래밍 언어가 파이썬 딕셔너리와 리스트에 상응하는 것을 갖고 있어서, JSON 는 협업하는 두 프로그램 사이의 데이터를 매우 자연스럽게 교환할 수 있습니다.

python for Informatics - charles severance (이광춘 역) 일부를 편집 수정

JSON (JavaScript Object Notation)

21 of 34

JSON으로 추출한 값을 Django DB에 저장할 수 있어요. (sqlite)

22 of 34

Django는 serialization framework으로 모델을 json으로 변환할 수 있어요.

https://docs.djangoproject.com/en/1.10/topics/serialization/

Django Rest Framework를 통해 인스턴스를 json 같은 형태로 직렬화(serializing) 또는  반직렬화(deserializing)하여 웹 API를 만들 수 있어요. �http://www.django-rest-framework.org/

23 of 34

Django Web Framework

앞서 만든 데이터 파일을

Django View로 연동해봅니다.

24 of 34

Django view

  • 저는 Django 모델을 사용하지 않고 파이썬 외부 파일을 view로 연결했어요.
  • 데이터 파일은 urls.py, views.py와 같은 위치(경로)에 저장하세요.
  • Django REST framework는 나중에…..도저언!?

event_script.py

event_data.py

스크립트 실행

파일 생성

데이터 전달

25 of 34

  1. Django URL / urls.py

  • 원 페이지 웹사이트를 만들고 싶어서 한 줄로 끝~

from django.conf.urls import url, includefrom . import viewsurlpatterns = [url(r'^runkorea/$', views.event_list, name='event_list'),]

26 of 34

2. Django View / views.py

  • python파일에서 외부 파이썬 파일에 있는 함수/변수를 호출하기

from file import function

  • Django View는요?

from . import filename

from . import views우리는 장고의 메소드와 blog 어플리케이션에서 사용할 모든 views들을 불러오고 있어요

.

장고걸스 튜토리얼 -urls.py 내용을 떠올려보세요.�https://tutorial.djangogirls.org/ko/django_views/

27 of 34

2. Django View / views.py

  • 파이썬 모듈처럼 event_data의 event_dict변수를 불러옵니다.
  • 장고 뷰 함수를 이용해 이벤트 리스트를 필터, 구분 할 수 있어요.
  • 저는 오늘 날짜를 기점으로 events 리스트를 분절해, 다음 이벤트 (upcoming_events) 리스트, 종료된 리스트 (past_events) 를 만들었어요.

from . import event_data

def event_list(request):events = event_data.event_dict#contextcontext = {'events': events, }return render(request, 'marathon/event_list.html', context)

28 of 34

3. Django Template / event_list.html

  • {% for %} 와 {% endfor %}사이에 목록의 모든 객체를 반복하세요.
  • 이제 html/css으로 예쁘게 꾸미면 끝!

<table>

{% for event in events %} <tbody><tr><td> {{ event.date }} </td><td> {{event.weather}} </td><td> {{ event.temperature }} </td>

[...생략]

</tr>{% endfor %}</tbody></table>

29 of 34

매일 크롤링하기

  • PythonAnywhere에서는 스크립트를 실행할 수 있는 서비스를 제공하고 있습니다.
  • 크롤링하는 프로그램(event_script.py) 경로를 넣고 매일 크롤링 할 수 있게 스케쥴링합니다.

30 of 34

그냥 궁금해서, Firebase

  • {% for %} 와 {% endfor %}사이에 목록의 모든 객체를 반복하세요.
  • 이제 html/css으로 예쁘게 꾸미면 끝!

31 of 34

어려웠던 점

  • 원본 사이트에서 사용자가 입력한 데이터가 불분명한 경우 (잘못된 정보를 입력) 지도 & 날씨 API 데이터를 호출하지 못했어요.��e.g) 날짜; 2016년인데, 2014로 입력… (왜죠?)� 장소; 한강 일대 (제대로 된 주소를 못찾아와요 ㅠ.ㅠ)� 지역; 체크박스에 표시를 하지 않았다면  ’지역'이라 출력하네요? ㅎㅎ�
  • 일일이 오류를 찾아 regex로 수정해야했는데, 오류 날짜만 수정하고, 나머지는 과감히 포기했습니다.

32 of 34

피드백 받기

장고 커뮤니티에 게시글을 올리면 많은선생님들이 좋은 숙제를 주십니다.

  • 문제가 생기면, 해결하는 과정을 통해 많은 것을 배울 수 있었어요.
  • 시간이 오래 걸려도 계속 하다보면 해답을 찾을 수 있었어요.
  • +1 성취감 향상.

장고걸스서울 슬랙, Django 페이스북을 적극 활용하세요.

33 of 34

마치며

  • 초보자도 BS4으로 웹크롤링을 할 수 있었어요.
  • Django로 간단한 프로젝트를 구현할 수 있었어요.
  • 파이썬과 장고로 비전공자/비개발자도 개발자 흉내를 낼 수 있었어요.
  • myproject.append(webcrawling_site)!
  • 장고걸스서울과 함께 장고를 알아가보아요.�http://slack.djangogirlsseoul.org/

34 of 34

감사합니다.