SlideShare una empresa de Scribd logo
생활 코딩 #2
: 싸이월드 백업하기
백승용 / seungyong.baek@gmail.com
생활 코딩:
가정 또는 업무의 반복적인 작업을 간단한 코딩으로 편안하게 하자.
개선 필요 사항
▪ 싸이월드는 한국의 오래된 SNS
▪ 와이프는 2004년 부터 현재 까지도 싸이월드를 이용중
▪ 지금은 가족의 일상 생활을 일기장 형식으로 이용하고 있음
▪ 그러나, 혹시라도 언제 서비스가 없어질지 모름(???)
▪ 그래서, 싸이월드 포스트의 글과 사진을 백업 받고 싶어함
▪ 2004년 ~ 2017년 까지 3,231개의 포스트가 게시되어 있음
• 실제로 백업을 받은 html 파일의 개수
▪ 따라서, 많은 포스트를 보다 쉽고 빠르게 백업할 방법이 필요
개선 목표
1
▪ 윈도우의 명령 프롬프트(CMD)에, 백업 대상 연도를
파라미터로 주어서 스크립트 실행
2
1
2
▪ 바탕화면에 지정한 연도의 폴더가 생성이 되고, 해당 연도의
포스트들을 html 형식의 파일로 저장
▪ 포스트의 개수와 html 파일 개수 비교 가능
▪ CYWORLD_XXXX.txt 파일에 포스트의, 모든 URL이 기록
되므로 포스트 개수 확인 가능
▪ 스크립트 위치: C:UsersSeungYong
▪ 스크립트 파일명: cyworld.py
준비 사항
1. 윈도우용 Python 설치
▪ https://www.python.org/downloads/
▪ Python 3.6.x 버전 설치
2. Python 라이브러리 설치
▪ 필요 표준 라이브러리: os, sys, re, random, time
▪ 추가 라이브러리: beautifulsoup4, selenium, pyautogui
▪ 설치된 추가 라이브러리 목록 확인
• C:>pip list --format=columns
▪ 추가 라이브러리 설치
• C:>pip install beautifulsoup4
• C:>pip install selenium
• C:>pip install pyautogui
▪ 추가 드라이버 설치
• 크롬 웹 드라이버(적당한 폴더에 다운로드 및 압축 해제)
• https://sites.google.com/a/chromium.org/chromedriver/d
ownloads
▪ 설치된 추가 라이브러리 목록 확인
▪ pip는 python 패키지 관리자로 python
설치시에 함께 설치됨
▪ 추가 라이브러리 설치
▪ 이미 설치된 경우에는 설치됨으로 나옴
필요 라이브러리/모듈/드라이버
Beautiful Soup
https://www.crummy.com/software/BeautifulSoup/
Selenium
http://www.seleniumhq.org/
라이브러리/모듈 설명
os
This module provides a portable way of using operating
system dependent functionality.
sys
This module provides access to some variables used or
maintained by the interpreter and to functions that
interact strongly with the interpreter.
re
This module provides regular expression matching
operations similar to those found in Perl.
random
This module implements pseudo-random number
generators for various distributions.
time This module provides various time-related functions.
selenium Selenium automates browsers.
beautifulsoup4
Beautiful Soup is a Python library for pulling data out of
HTML and XML files.
pyautogui
PyAutoGUI is a cross-platform GUI automation Python
module for human beings. Used to programmatically
control the mouse & keyboard.
ChromeDriver
WebDriver is an open source tool for automated testing
of webapps across many browsers.
• 설명은 공식 홈페이지의 설명 인용(www.python.org, Beautiful Soup, Selenium,
PyAutoGUI, ChromeDriver)
• 실제 사용 방법은 코드에서 설명
PyAutoGUI
https://github.com/asweigart/pyautogui
ChromeDriver
https://sites.google.com/a/chromium.org/chromedriver/home
전체 코드
2
1
1
▪ download_cyworld() 함수
1. 백업 대상 연도를 매개 변수로 받음
2. 크롬 브라우저 시작
3. 싸이월드 로그인
4. 백업 대상 연도의 모든 포스트 리스팅
5. 모든 포스트를 html 파일로 저장
2
▪ 스크립트 시작점
1. 스크립트가 정상적으로 실행이 되었을 경우
2. 필요한 모듈을 임포트하고
3. download_cyworld() 함수로 해당 연도를 매개
변수로 전달하여 실행
코드 설명 #1
라인 설명
86
▪ cyworld.py라는 스크립트가 아래의 **와 같이 독립적으로
실행될 때만 86번 라인 이후의 코드가 바로 실행됨
▪ 즉, 다른 스크립트에서 모듈로 임포트되는 경우에는 바로
실행되지 않음
** C:>cyworld.py 2009
88~100
▪ 표준 및 추가 라이브러리 임포트
▪ BeautifulSoup은 “as”로 임포트 하였기 때문에, BS라는
별칭으로 사용됨
▪ selenium expected_conditions는 EC로 사용됨
102~106
▪ cyworld.py 스크립트로 전달된 매개 변수의 개수가, 2개
로 올바르게 입력된 경우, 매개 변수를 변수로 할당하고
download_cyworld()함수 호출
▪ 아래의 **와 같이 실행된 경우, len(sys.argv) == 2가 됨
• sys.argv[0]=cyworld.py
• sys.argv[1]=2009  input_year로 할당
▪ 즉, download_cyworld(2009)의 형태로 함수 호출
** C:>cyworld.py 2009
107~110
▪ cyworld.py 스크립트로 전달된 매개 변수의 개수가 2개가
아닌 경우에는 안내 메시지 출력
코드 설명 #2
라인 설명
4 ▪ input_year를 매개 변수로 받는 함수 정의
6 ▪ ChromeDriver 설치(압축 해제) 경로를 명시
7, 8
▪ 웹 드라이버를 이용해 크롬 브라우저를 실행시키고
cyworld 객체로 생성한 후에, 창을 최대화 함
▪ 크롬 브라우저가 실행이 되면, 소프트웨어에 의해 제어됨
이 표시됨
• “코드 설명 #2 - 부가설명 #2” 참조
11 ▪ 브라우저에서 로그인 페이지를 로딩
12, 13 ▪ 로그인 정보(uid, upw)를 브라우저로 전달
14 ▪ “로그인” 버튼을 클릭
15 ▪ “내싸이홈가기”가 클릭이 가능한 상태가 될 때까지 대기
16 ▪ “내싸이홈가기”를 클릭
17
▪ time 모듈을 사용하여 5초간 대기
▪ 실제 사람처럼 웹 브라우저를 조작하므로, 웹 페이지가
정상적으로 로드 될 때 까지, WebDriverWait()와
time.sleep()으로 적정한 대기 코드가 필수
20~26
▪ 11~17 라인과 비슷한 방식으로 브라우저 조작
▪ 특정 연도의 포스트 리스트 첫 페이지를 가져옴
▪ sDate, eDate에 ’00’이 붙는 것은, 싸이월드 특성
• cyworld.find_element_by_xxxxxxxx로 시작하는, 모든 코드는 “코드
설명 #2 - 부가설명 #1” 참조
• 브라우저 조작은 “코드 설명 #2 - 부가설명 #2” 참조
코드 설명 #2 - 부가 설명 #1(웹 ELEMENT 찾기)
1. 브라우저에서 대상 요소 우 클릭  검사
2. Elements 창에서 해당 요소를 우 클릭
3. 필요한 요소를 복사 해서 사용
▪ 코드에서 아래와 같은 모든 라인은 이 방법을 통하여 찾음
▪ id의 경우 Elements 창에서 확인 가능
• cyworld.find_element_by_id
• cyworld.find_element_by_xpath
• cyworld.find_element_by_css_selector
▪ xpath: XML Path  참고: https://ko.Wikipedia.org/wiki/XPath
▪ css selector: CSS Selector  참고: http://www.nextree.co.kr/p8468
▪ 웹 페이지에서 가장 unique하고 변경이 적을 만한 요소의 사용을 권장
코드 설명 #2 - 부가 설명 #2(브라우저 조작)
라인 11: 로그인 페이지
라인 12: uid
라인 13: upw
라인 14: //*[@id="tab_cont1"]/div/input
라인 15, 16: //*[@id="loginbox"]/ul/li[1]/a
라인 20: //*[@id="all"]
라인 21, 22: //*[@id="allArea"]/div/ul/li[2]/label/span
라인 23, 24: sDate, eDate
라인 25, 26: //*[@id="allArea"]/div/div/button
라인 7: 웹 드라이버로 제어되는 크롬 브라우저 실행, cyworld 객체
코드 설명 #3
라인 설명
29~37
▪ 20~26 라인을 통해 2009년 포스트의 첫 페이지가 표시됨
▪ 그러나, 모든 포스트가 아닌 최근 24개만 표시가 됨
▪ 페이지 하단의 “+” 버튼으로 모든 포스트의 목록을 표시
▪ “+” 버튼 누르기는 xpath로는 원하는 구현이 되지 않아
css selector 사용
▪ while 구문으로 “+”가 나타나면 계속 클릭
▪ 더 이상 “+“ 버튼이 나타나지 않아, selenium exception이
발생하면 메시지를 표시하고 pass 시킴
40~43
▪ cyworld 객체의 page_source를 beautifulsoup를 이용하
여 파싱하고 soup 객체 생성
▪ 각 포스트의 url들을 저장할 빈 post_urls set 생성
45~48
▪ soup 객체에서 포스트 URL이 담긴 “postSection” 검색
▪ 검색된 “postSection”내에서, 간단한 정규 표현식으로
“/home/25967997/post/”로 시작하는 html “a” tag만 검색
하여 link로 전달
▪ link에서 “href” 속성의 값(URL)만 link_url로 생성
▪ link_url로 각 포스트의 전체 URL을 생성
▪ post_urls set에 각 포스트의 전체 URL을 추가
51~53
▪ 해당 연도의 전체 포스트 개수가 표기된 “제목“ 출력
▪ 실제로 post_urls set에 저장된 post_url의 개수 출력
• 브라우저 조작과 변수는 “코드 설명 #3 - 부가 설명 #1, #2” 참조
코드 설명 #3 - 부가 설명 #1(브라우저 조작)
라인 31, 33: #divMoreBtn > button
▪ soup 객체: 아래의 항목들을 검색하고 참조할 수 있음
• postTitle
• postSection
• 개별 포스트의 URL
• 개별 포스트의 subject
• 등등등
코드 설명 #3 - 부가 설명 #2(45~48 라인 변수)
▪ 라인 45: link
<a href="/home/25967997/post/4A512E18280003187AFA6401" onclick="Post.ClickView('4A512E18280003187AFA6401');return false;">
<span class="date">7.6</span>
<h3 class="subject">산책로 입구</h3>
<div class="data"><figure alt="산책로 입구 " class="postImage" style="background-
image:url('http://cythumb.cyworld.com/269x269/cyimg25.cyworld.com/common/file_down.asp?redirect=%2F250012%2F2009%2F7%2F6%2F62%2F200907060
74949_25967997.jpg');"></figure>
</div>
</a>
▪ 라인 46: link_url
/home/25967997/post/4A512E18280003187AFA6401
▪ 라인 47: post_url
http://cy.cyworld.com/home/25967997/post/4A512E18280003187AFA6401
▪ 라인 48: post_urls
http://cy.cyworld.com/home/25967997/post/4A512E18280003187AFA6401
http://cy.cyworld.com/home/25967997/post/4A512ECC3DC003187AFA6401
http://cy.cyworld.com/home/25967997/post/4A512F08920003187AFAA801
http://cy.cyworld.com/home/25967997/post/4A512C38014003187AFA6401
……………
코드 설명 #4
라인 설명
56, 57
▪ html 파일 저장 폴더인 save_dir 정의
▪ 포스트 URL을 저장할 텍스트 파일 post_list 정의
59, 60 ▪ save_dir이 없으면, 폴더 생성
62, 63 ▪ post_list가 없으면, 쓰기 모드로 신규 파일 생성
65 ▪ post_urls에서 각 URL을 하나씩 post로 전달
66 ▪ 브라우저에서 해당 페이지를 로딩
67
▪ 페이지 하단의 “댓글 박스”가 로딩될 때까지 대기
▪ 사진이 많아서 로딩이 오래 걸릴 경우를 대비하여 타임아
웃을 보다 길게 설정
68 ▪ 해당 포스트의 “등록일시”를 post_date로 생성
69
▪ save_dir과 post_date를 슬라이싱하여 입력 파일 명 생성
▪ random 함수는 제목이 없는 포스트의 경우, 파일명이 중
복되어 제대로 저장되지 않는 경우가 발생. 이를 방지하
기 위하여 저장 파일명에 임의의 정수를 추가
70 ▪ CYWORLD_XXXX.txt에 저장될 파일명과 URL을 기록
72~79
▪ pyautogui로 웹 브라우저의 “우 클릭" “다른 이름으로
저장”  “파일명 입력”  “저장”을 구현
▪ 브라우저의 “다른 이름으로 저장” 기능은, OS가 제어를
하는 영역이라 selenium(브라우저)에서는 제어 불가능
82, 83 ▪ post_list(CYWORLD_XXXX.txt) 및 웹 브라우저 닫기
• 브라우저 조작과 변수는 “코드 설명 #4 - 부가 설명 #1” 참조
코드 설명 #4 - 부가 설명 #1(브라우저 조작 및 변수)
라인 67: //*[@id="inputWrap123456"]/textarea
라인 68: #postData > div.postInfo > ul > li.date > p
▪ 라인 68: post_date
2009.07.06 08:42 (업로드 2009.07.06 08:42)
▪ 라인 69: save_file_name
C:UsersSeungYongDesktop200907.06_39_
• 실제로 저장될 파일명은 save_file_name + “해당 포스트의 제목“
• 예를 들어 제목이 “제주도”라면 아래와 같은 파일명으로 저장됨
• C:UsersSeungYongDesktop200907.06_39_제주도
▪ C:UsersSeungYongDesktop2009CYWORLD_2009.txt 파일의 내용
코드 스타일 점검
▪ 코드의 문법 및 스타일 점검을 위하여 pycodestyle 사용
▪ pycodestyle은 기존의 pep8의 이름이 변경된 것임
▪ 여러 항목의 코드 스타일에 대한 체크를 해 줌
▪ E501: 일반적으로 79 컬럼 내에 코드를 작성할 것을 권고하는 에러
• C:UsersSeungYong>pip install pycodestyle
• C:UsersSeungYong>pycodestyle cyworld.py
고려 사항
1. 이 스크립트는 다양한 경우의 예외 또는 에러가 발생할 수 있으나, 이에 대한 오류 처리 코드가 없음
▪ 모든 오류를 코드로 처리하는 것보다, 단순 재실행하는 방법이 보다 생산성이 높을 것으로 생각
2. 10회를 수행하였을 때 PC, 네트워크, 서버등의 다양한 원인으로 2~3회 이상 실패할 수 있음
▪ 이러한 경우, 바탕화면의 폴더를 지우고 재실행
3. 웹 브라우저를 직접 실행하는 형태여서, 스크립트를 실행하면 PC를 사용할 수 없음
▪ pyautogui 모듈의 경우, 마우스 및 키보드를 직접 제어하기 때문에 사용자의 개입시에 오류 발생
▪ 스크립트를 수행하고 취침하는 방식을 권장
▪ PhantomJS를 이용하여 headless로도 시도를 하여 보았으나, 제대로 수행되지 않음(실력의 한계)
4. 백업 수행 속도는 환경에 따라 다르나, 분당 평균 6개 포스트~10개 정도
5. 실행시에 아래와 같은 에러는 브라우저, selenium, ChromeDriver등 버전에 따라 나오기도 하고 안 나오기도 함
▪ 그러나, 싸이월드 포스트를 html 파일로 백업하는 것에는 지장 없음 http://phantomjs.org/
감사합니다.

Más contenido relacionado

La actualidad más candente

[JCO 컨퍼런스] 웹사이트 Front-End 성능 최적화
[JCO 컨퍼런스] 웹사이트 Front-End 성능 최적화[JCO 컨퍼런스] 웹사이트 Front-End 성능 최적화
[JCO 컨퍼런스] 웹사이트 Front-End 성능 최적화흥래 김
 
구글앱엔진+스프링+스프링datajpa+메이븐
구글앱엔진+스프링+스프링datajpa+메이븐구글앱엔진+스프링+스프링datajpa+메이븐
구글앱엔진+스프링+스프링datajpa+메이븐라한사 아
 
빠른 프로토타이핑을 위한 웹앱 자동화 툴 - YEOMAN
빠른 프로토타이핑을 위한 웹앱 자동화 툴 - YEOMAN빠른 프로토타이핑을 위한 웹앱 자동화 툴 - YEOMAN
빠른 프로토타이핑을 위한 웹앱 자동화 툴 - YEOMAN정호 전
 
Vue SSR vs Prerender
Vue SSR vs PrerenderVue SSR vs Prerender
Vue SSR vs PrerenderChangwan Jun
 
Envoy 를 이용한 코드 배포 자동화
Envoy 를 이용한 코드 배포 자동화Envoy 를 이용한 코드 배포 자동화
Envoy 를 이용한 코드 배포 자동화Juwon Kim
 
Resource Handling in Spring MVC
Resource Handling in Spring MVCResource Handling in Spring MVC
Resource Handling in Spring MVCArawn Park
 
Jenkins with Unity3d & Android
Jenkins with Unity3d & Android Jenkins with Unity3d & Android
Jenkins with Unity3d & Android 종국 임
 
Cloud ide를 이용한_모바일_개발의_가능성과_전망
Cloud ide를 이용한_모바일_개발의_가능성과_전망Cloud ide를 이용한_모바일_개발의_가능성과_전망
Cloud ide를 이용한_모바일_개발의_가능성과_전망Sung-tae Ryu
 
[145]5년간의네이버웹엔진개발삽질기그리고 김효
[145]5년간의네이버웹엔진개발삽질기그리고 김효[145]5년간의네이버웹엔진개발삽질기그리고 김효
[145]5년간의네이버웹엔진개발삽질기그리고 김효NAVER D2
 
make hybrid app.
make hybrid app.make hybrid app.
make hybrid app.jiseob kim
 
Jenkins와 Gitlab으로 쉽고 빠르게 구축하는 협업시스템
Jenkins와 Gitlab으로 쉽고 빠르게 구축하는 협업시스템Jenkins와 Gitlab으로 쉽고 빠르게 구축하는 협업시스템
Jenkins와 Gitlab으로 쉽고 빠르게 구축하는 협업시스템Park JoongSoo
 
[오픈소스컨설팅] Atlassian Confluence User Guide Part-1
[오픈소스컨설팅] Atlassian Confluence User Guide Part-1[오픈소스컨설팅] Atlassian Confluence User Guide Part-1
[오픈소스컨설팅] Atlassian Confluence User Guide Part-1Ji-Woong Choi
 
Node.js + Websocket 삽질기
Node.js + Websocket 삽질기Node.js + Websocket 삽질기
Node.js + Websocket 삽질기Paprikhan
 
안드로이드 개발에 유용한 도구들
안드로이드 개발에 유용한 도구들안드로이드 개발에 유용한 도구들
안드로이드 개발에 유용한 도구들Sewon Ann
 
[111217 아꿈사연말모임] 웹소켓과온라인게임
[111217 아꿈사연말모임] 웹소켓과온라인게임[111217 아꿈사연말모임] 웹소켓과온라인게임
[111217 아꿈사연말모임] 웹소켓과온라인게임sung ki choi
 

La actualidad más candente (20)

[JCO 컨퍼런스] 웹사이트 Front-End 성능 최적화
[JCO 컨퍼런스] 웹사이트 Front-End 성능 최적화[JCO 컨퍼런스] 웹사이트 Front-End 성능 최적화
[JCO 컨퍼런스] 웹사이트 Front-End 성능 최적화
 
구글앱엔진+스프링+스프링datajpa+메이븐
구글앱엔진+스프링+스프링datajpa+메이븐구글앱엔진+스프링+스프링datajpa+메이븐
구글앱엔진+스프링+스프링datajpa+메이븐
 
빠른 프로토타이핑을 위한 웹앱 자동화 툴 - YEOMAN
빠른 프로토타이핑을 위한 웹앱 자동화 툴 - YEOMAN빠른 프로토타이핑을 위한 웹앱 자동화 툴 - YEOMAN
빠른 프로토타이핑을 위한 웹앱 자동화 툴 - YEOMAN
 
Cooking jquery
Cooking jqueryCooking jquery
Cooking jquery
 
AWS + Docker in Vingle
AWS + Docker in VingleAWS + Docker in Vingle
AWS + Docker in Vingle
 
Vue SSR vs Prerender
Vue SSR vs PrerenderVue SSR vs Prerender
Vue SSR vs Prerender
 
Envoy 를 이용한 코드 배포 자동화
Envoy 를 이용한 코드 배포 자동화Envoy 를 이용한 코드 배포 자동화
Envoy 를 이용한 코드 배포 자동화
 
Goorm소개
Goorm소개Goorm소개
Goorm소개
 
Resource Handling in Spring MVC
Resource Handling in Spring MVCResource Handling in Spring MVC
Resource Handling in Spring MVC
 
Jenkins with Unity3d & Android
Jenkins with Unity3d & Android Jenkins with Unity3d & Android
Jenkins with Unity3d & Android
 
Node.js 기본
Node.js 기본Node.js 기본
Node.js 기본
 
Modern PHP
Modern PHPModern PHP
Modern PHP
 
Cloud ide를 이용한_모바일_개발의_가능성과_전망
Cloud ide를 이용한_모바일_개발의_가능성과_전망Cloud ide를 이용한_모바일_개발의_가능성과_전망
Cloud ide를 이용한_모바일_개발의_가능성과_전망
 
[145]5년간의네이버웹엔진개발삽질기그리고 김효
[145]5년간의네이버웹엔진개발삽질기그리고 김효[145]5년간의네이버웹엔진개발삽질기그리고 김효
[145]5년간의네이버웹엔진개발삽질기그리고 김효
 
make hybrid app.
make hybrid app.make hybrid app.
make hybrid app.
 
Jenkins와 Gitlab으로 쉽고 빠르게 구축하는 협업시스템
Jenkins와 Gitlab으로 쉽고 빠르게 구축하는 협업시스템Jenkins와 Gitlab으로 쉽고 빠르게 구축하는 협업시스템
Jenkins와 Gitlab으로 쉽고 빠르게 구축하는 협업시스템
 
[오픈소스컨설팅] Atlassian Confluence User Guide Part-1
[오픈소스컨설팅] Atlassian Confluence User Guide Part-1[오픈소스컨설팅] Atlassian Confluence User Guide Part-1
[오픈소스컨설팅] Atlassian Confluence User Guide Part-1
 
Node.js + Websocket 삽질기
Node.js + Websocket 삽질기Node.js + Websocket 삽질기
Node.js + Websocket 삽질기
 
안드로이드 개발에 유용한 도구들
안드로이드 개발에 유용한 도구들안드로이드 개발에 유용한 도구들
안드로이드 개발에 유용한 도구들
 
[111217 아꿈사연말모임] 웹소켓과온라인게임
[111217 아꿈사연말모임] 웹소켓과온라인게임[111217 아꿈사연말모임] 웹소켓과온라인게임
[111217 아꿈사연말모임] 웹소켓과온라인게임
 

Similar a 생활 코딩 #2(Simple Web Scraping with Python #2)

Polymer따라잡기
Polymer따라잡기Polymer따라잡기
Polymer따라잡기Han Jung Hyun
 
Django로 배우는 쉽고 빠른 웹개발 study 자료
Django로 배우는 쉽고 빠른 웹개발 study 자료Django로 배우는 쉽고 빠른 웹개발 study 자료
Django로 배우는 쉽고 빠른 웹개발 study 자료Han Sung Kim
 
웹 크롤링 (Web scraping) 의 이해
웹 크롤링 (Web scraping) 의 이해웹 크롤링 (Web scraping) 의 이해
웹 크롤링 (Web scraping) 의 이해2minchul
 
[PyConKR 2014] 30분만에 따라하는 동시성 스크래퍼
[PyConKR 2014] 30분만에 따라하는 동시성 스크래퍼[PyConKR 2014] 30분만에 따라하는 동시성 스크래퍼
[PyConKR 2014] 30분만에 따라하는 동시성 스크래퍼Cheol Kang
 
알아봅시다, Polymer: Web Components & Web Animations
알아봅시다, Polymer: Web Components & Web Animations알아봅시다, Polymer: Web Components & Web Animations
알아봅시다, Polymer: Web Components & Web AnimationsChang W. Doh
 
Django - CRUD 기능 구현
Django - CRUD 기능 구현Django - CRUD 기능 구현
Django - CRUD 기능 구현Jessica Lee
 
버전관리시스템 종류와 소개
버전관리시스템 종류와 소개버전관리시스템 종류와 소개
버전관리시스템 종류와 소개Jong-il Seok
 
JQuery를 이용하여 웹 위젯 작성하기_(주)시스포유아이앤씨
JQuery를 이용하여 웹 위젯 작성하기_(주)시스포유아이앤씨JQuery를 이용하여 웹 위젯 작성하기_(주)시스포유아이앤씨
JQuery를 이용하여 웹 위젯 작성하기_(주)시스포유아이앤씨sys4u
 
141118 최창원 웹크롤러제작
141118 최창원 웹크롤러제작141118 최창원 웹크롤러제작
141118 최창원 웹크롤러제작Changwon Choe
 
2021년 4월 10일 개발자 이야기
2021년 4월 10일 개발자 이야기2021년 4월 10일 개발자 이야기
2021년 4월 10일 개발자 이야기Jay Park
 
인프콘 2022 - Rust 크로스 플랫폼 프로그래밍
인프콘 2022 - Rust 크로스 플랫폼 프로그래밍인프콘 2022 - Rust 크로스 플랫폼 프로그래밍
인프콘 2022 - Rust 크로스 플랫폼 프로그래밍Chris Ohk
 
어그로월드 Season1 - Aggro World season 1
어그로월드 Season1 - Aggro World season 1어그로월드 Season1 - Aggro World season 1
어그로월드 Season1 - Aggro World season 1bingoori
 
브라우저는 어떻게 동작하는가?
브라우저는 어떻게 동작하는가?브라우저는 어떻게 동작하는가?
브라우저는 어떻게 동작하는가?Minseok Jang
 
Unity Auto Build iOS
Unity Auto Build iOSUnity Auto Build iOS
Unity Auto Build iOSGiseok Lee
 
백기선의 스프링 부트
백기선의 스프링 부트백기선의 스프링 부트
백기선의 스프링 부트Keesun Baik
 
CodeSnippets and Macro
CodeSnippets and MacroCodeSnippets and Macro
CodeSnippets and MacroYoung Woo Lee
 
[123] electron 김성훈
[123] electron 김성훈[123] electron 김성훈
[123] electron 김성훈NAVER D2
 

Similar a 생활 코딩 #2(Simple Web Scraping with Python #2) (20)

Polymer따라잡기
Polymer따라잡기Polymer따라잡기
Polymer따라잡기
 
Django로 배우는 쉽고 빠른 웹개발 study 자료
Django로 배우는 쉽고 빠른 웹개발 study 자료Django로 배우는 쉽고 빠른 웹개발 study 자료
Django로 배우는 쉽고 빠른 웹개발 study 자료
 
웹 크롤링 (Web scraping) 의 이해
웹 크롤링 (Web scraping) 의 이해웹 크롤링 (Web scraping) 의 이해
웹 크롤링 (Web scraping) 의 이해
 
Node.js 첫걸음
Node.js 첫걸음Node.js 첫걸음
Node.js 첫걸음
 
[PyConKR 2014] 30분만에 따라하는 동시성 스크래퍼
[PyConKR 2014] 30분만에 따라하는 동시성 스크래퍼[PyConKR 2014] 30분만에 따라하는 동시성 스크래퍼
[PyConKR 2014] 30분만에 따라하는 동시성 스크래퍼
 
알아봅시다, Polymer: Web Components & Web Animations
알아봅시다, Polymer: Web Components & Web Animations알아봅시다, Polymer: Web Components & Web Animations
알아봅시다, Polymer: Web Components & Web Animations
 
Html5
Html5 Html5
Html5
 
Django - CRUD 기능 구현
Django - CRUD 기능 구현Django - CRUD 기능 구현
Django - CRUD 기능 구현
 
버전관리시스템 종류와 소개
버전관리시스템 종류와 소개버전관리시스템 종류와 소개
버전관리시스템 종류와 소개
 
JQuery를 이용하여 웹 위젯 작성하기_(주)시스포유아이앤씨
JQuery를 이용하여 웹 위젯 작성하기_(주)시스포유아이앤씨JQuery를 이용하여 웹 위젯 작성하기_(주)시스포유아이앤씨
JQuery를 이용하여 웹 위젯 작성하기_(주)시스포유아이앤씨
 
141118 최창원 웹크롤러제작
141118 최창원 웹크롤러제작141118 최창원 웹크롤러제작
141118 최창원 웹크롤러제작
 
7. html5 api
7. html5 api7. html5 api
7. html5 api
 
2021년 4월 10일 개발자 이야기
2021년 4월 10일 개발자 이야기2021년 4월 10일 개발자 이야기
2021년 4월 10일 개발자 이야기
 
인프콘 2022 - Rust 크로스 플랫폼 프로그래밍
인프콘 2022 - Rust 크로스 플랫폼 프로그래밍인프콘 2022 - Rust 크로스 플랫폼 프로그래밍
인프콘 2022 - Rust 크로스 플랫폼 프로그래밍
 
어그로월드 Season1 - Aggro World season 1
어그로월드 Season1 - Aggro World season 1어그로월드 Season1 - Aggro World season 1
어그로월드 Season1 - Aggro World season 1
 
브라우저는 어떻게 동작하는가?
브라우저는 어떻게 동작하는가?브라우저는 어떻게 동작하는가?
브라우저는 어떻게 동작하는가?
 
Unity Auto Build iOS
Unity Auto Build iOSUnity Auto Build iOS
Unity Auto Build iOS
 
백기선의 스프링 부트
백기선의 스프링 부트백기선의 스프링 부트
백기선의 스프링 부트
 
CodeSnippets and Macro
CodeSnippets and MacroCodeSnippets and Macro
CodeSnippets and Macro
 
[123] electron 김성훈
[123] electron 김성훈[123] electron 김성훈
[123] electron 김성훈
 

Más de SeungYong Baek

데이터 레이크 알아보기(Learn about Data Lake)
데이터 레이크 알아보기(Learn about Data Lake)데이터 레이크 알아보기(Learn about Data Lake)
데이터 레이크 알아보기(Learn about Data Lake)SeungYong Baek
 
DevOps - CI/CD 알아보기
DevOps - CI/CD 알아보기DevOps - CI/CD 알아보기
DevOps - CI/CD 알아보기SeungYong Baek
 
NetApp AI Control Plane
NetApp AI Control PlaneNetApp AI Control Plane
NetApp AI Control PlaneSeungYong Baek
 
오픈소스 모니터링 알아보기(Learn about opensource monitoring)
오픈소스 모니터링 알아보기(Learn about opensource monitoring)오픈소스 모니터링 알아보기(Learn about opensource monitoring)
오픈소스 모니터링 알아보기(Learn about opensource monitoring)SeungYong Baek
 
데이터분석 알아보기(Learn about basic data analysis)
데이터분석 알아보기(Learn about  basic data analysis)데이터분석 알아보기(Learn about  basic data analysis)
데이터분석 알아보기(Learn about basic data analysis)SeungYong Baek
 
하둡 알아보기(Learn about Hadoop basic), NetApp FAS NFS Connector for Hadoop
하둡 알아보기(Learn about Hadoop basic), NetApp FAS NFS Connector for Hadoop하둡 알아보기(Learn about Hadoop basic), NetApp FAS NFS Connector for Hadoop
하둡 알아보기(Learn about Hadoop basic), NetApp FAS NFS Connector for HadoopSeungYong Baek
 

Más de SeungYong Baek (6)

데이터 레이크 알아보기(Learn about Data Lake)
데이터 레이크 알아보기(Learn about Data Lake)데이터 레이크 알아보기(Learn about Data Lake)
데이터 레이크 알아보기(Learn about Data Lake)
 
DevOps - CI/CD 알아보기
DevOps - CI/CD 알아보기DevOps - CI/CD 알아보기
DevOps - CI/CD 알아보기
 
NetApp AI Control Plane
NetApp AI Control PlaneNetApp AI Control Plane
NetApp AI Control Plane
 
오픈소스 모니터링 알아보기(Learn about opensource monitoring)
오픈소스 모니터링 알아보기(Learn about opensource monitoring)오픈소스 모니터링 알아보기(Learn about opensource monitoring)
오픈소스 모니터링 알아보기(Learn about opensource monitoring)
 
데이터분석 알아보기(Learn about basic data analysis)
데이터분석 알아보기(Learn about  basic data analysis)데이터분석 알아보기(Learn about  basic data analysis)
데이터분석 알아보기(Learn about basic data analysis)
 
하둡 알아보기(Learn about Hadoop basic), NetApp FAS NFS Connector for Hadoop
하둡 알아보기(Learn about Hadoop basic), NetApp FAS NFS Connector for Hadoop하둡 알아보기(Learn about Hadoop basic), NetApp FAS NFS Connector for Hadoop
하둡 알아보기(Learn about Hadoop basic), NetApp FAS NFS Connector for Hadoop
 

Último

2024년 5월 27일 개발자 이야기 - AWS 람다의 내부 동작 방식 외
2024년 5월 27일 개발자 이야기 - AWS 람다의 내부 동작 방식 외2024년 5월 27일 개발자 이야기 - AWS 람다의 내부 동작 방식 외
2024년 5월 27일 개발자 이야기 - AWS 람다의 내부 동작 방식 외Jay Park
 
INU Graduation Powerpoint-Rabbit FootPrint
INU Graduation Powerpoint-Rabbit FootPrintINU Graduation Powerpoint-Rabbit FootPrint
INU Graduation Powerpoint-Rabbit FootPrintahghwo99
 
인천대학교 컴퓨터공학과 아틀란티스 졸업작품 commINUty PPT
인천대학교 컴퓨터공학과 아틀란티스 졸업작품 commINUty PPT인천대학교 컴퓨터공학과 아틀란티스 졸업작품 commINUty PPT
인천대학교 컴퓨터공학과 아틀란티스 졸업작품 commINUty PPTpcupcu20831004
 
캡스톤-디자인-최종-발표-(대상혁) 24년도 졸업작품발표회 ppt.pptx
캡스톤-디자인-최종-발표-(대상혁) 24년도 졸업작품발표회 ppt.pptx캡스톤-디자인-최종-발표-(대상혁) 24년도 졸업작품발표회 ppt.pptx
캡스톤-디자인-최종-발표-(대상혁) 24년도 졸업작품발표회 ppt.pptxcho9759
 
인천대학교 캡스톤디자인(2) Pencil me 프레젠테이션 발표자료 파일
인천대학교 캡스톤디자인(2) Pencil me 프레젠테이션 발표자료 파일인천대학교 캡스톤디자인(2) Pencil me 프레젠테이션 발표자료 파일
인천대학교 캡스톤디자인(2) Pencil me 프레젠테이션 발표자료 파일justuser0129
 
암호화 보안USB & 외장하드 중앙관리 솔루션 ‘DataLocker SafeConsole’_DATASHEET
암호화 보안USB & 외장하드 중앙관리 솔루션 ‘DataLocker SafeConsole’_DATASHEET암호화 보안USB & 외장하드 중앙관리 솔루션 ‘DataLocker SafeConsole’_DATASHEET
암호화 보안USB & 외장하드 중앙관리 솔루션 ‘DataLocker SafeConsole’_DATASHEETSoftwide Security
 

Último (6)

2024년 5월 27일 개발자 이야기 - AWS 람다의 내부 동작 방식 외
2024년 5월 27일 개발자 이야기 - AWS 람다의 내부 동작 방식 외2024년 5월 27일 개발자 이야기 - AWS 람다의 내부 동작 방식 외
2024년 5월 27일 개발자 이야기 - AWS 람다의 내부 동작 방식 외
 
INU Graduation Powerpoint-Rabbit FootPrint
INU Graduation Powerpoint-Rabbit FootPrintINU Graduation Powerpoint-Rabbit FootPrint
INU Graduation Powerpoint-Rabbit FootPrint
 
인천대학교 컴퓨터공학과 아틀란티스 졸업작품 commINUty PPT
인천대학교 컴퓨터공학과 아틀란티스 졸업작품 commINUty PPT인천대학교 컴퓨터공학과 아틀란티스 졸업작품 commINUty PPT
인천대학교 컴퓨터공학과 아틀란티스 졸업작품 commINUty PPT
 
캡스톤-디자인-최종-발표-(대상혁) 24년도 졸업작품발표회 ppt.pptx
캡스톤-디자인-최종-발표-(대상혁) 24년도 졸업작품발표회 ppt.pptx캡스톤-디자인-최종-발표-(대상혁) 24년도 졸업작품발표회 ppt.pptx
캡스톤-디자인-최종-발표-(대상혁) 24년도 졸업작품발표회 ppt.pptx
 
인천대학교 캡스톤디자인(2) Pencil me 프레젠테이션 발표자료 파일
인천대학교 캡스톤디자인(2) Pencil me 프레젠테이션 발표자료 파일인천대학교 캡스톤디자인(2) Pencil me 프레젠테이션 발표자료 파일
인천대학교 캡스톤디자인(2) Pencil me 프레젠테이션 발표자료 파일
 
암호화 보안USB & 외장하드 중앙관리 솔루션 ‘DataLocker SafeConsole’_DATASHEET
암호화 보안USB & 외장하드 중앙관리 솔루션 ‘DataLocker SafeConsole’_DATASHEET암호화 보안USB & 외장하드 중앙관리 솔루션 ‘DataLocker SafeConsole’_DATASHEET
암호화 보안USB & 외장하드 중앙관리 솔루션 ‘DataLocker SafeConsole’_DATASHEET
 

생활 코딩 #2(Simple Web Scraping with Python #2)

  • 1. 생활 코딩 #2 : 싸이월드 백업하기 백승용 / seungyong.baek@gmail.com 생활 코딩: 가정 또는 업무의 반복적인 작업을 간단한 코딩으로 편안하게 하자.
  • 2. 개선 필요 사항 ▪ 싸이월드는 한국의 오래된 SNS ▪ 와이프는 2004년 부터 현재 까지도 싸이월드를 이용중 ▪ 지금은 가족의 일상 생활을 일기장 형식으로 이용하고 있음 ▪ 그러나, 혹시라도 언제 서비스가 없어질지 모름(???) ▪ 그래서, 싸이월드 포스트의 글과 사진을 백업 받고 싶어함 ▪ 2004년 ~ 2017년 까지 3,231개의 포스트가 게시되어 있음 • 실제로 백업을 받은 html 파일의 개수 ▪ 따라서, 많은 포스트를 보다 쉽고 빠르게 백업할 방법이 필요
  • 3. 개선 목표 1 ▪ 윈도우의 명령 프롬프트(CMD)에, 백업 대상 연도를 파라미터로 주어서 스크립트 실행 2 1 2 ▪ 바탕화면에 지정한 연도의 폴더가 생성이 되고, 해당 연도의 포스트들을 html 형식의 파일로 저장 ▪ 포스트의 개수와 html 파일 개수 비교 가능 ▪ CYWORLD_XXXX.txt 파일에 포스트의, 모든 URL이 기록 되므로 포스트 개수 확인 가능 ▪ 스크립트 위치: C:UsersSeungYong ▪ 스크립트 파일명: cyworld.py
  • 4. 준비 사항 1. 윈도우용 Python 설치 ▪ https://www.python.org/downloads/ ▪ Python 3.6.x 버전 설치 2. Python 라이브러리 설치 ▪ 필요 표준 라이브러리: os, sys, re, random, time ▪ 추가 라이브러리: beautifulsoup4, selenium, pyautogui ▪ 설치된 추가 라이브러리 목록 확인 • C:>pip list --format=columns ▪ 추가 라이브러리 설치 • C:>pip install beautifulsoup4 • C:>pip install selenium • C:>pip install pyautogui ▪ 추가 드라이버 설치 • 크롬 웹 드라이버(적당한 폴더에 다운로드 및 압축 해제) • https://sites.google.com/a/chromium.org/chromedriver/d ownloads ▪ 설치된 추가 라이브러리 목록 확인 ▪ pip는 python 패키지 관리자로 python 설치시에 함께 설치됨 ▪ 추가 라이브러리 설치 ▪ 이미 설치된 경우에는 설치됨으로 나옴
  • 5. 필요 라이브러리/모듈/드라이버 Beautiful Soup https://www.crummy.com/software/BeautifulSoup/ Selenium http://www.seleniumhq.org/ 라이브러리/모듈 설명 os This module provides a portable way of using operating system dependent functionality. sys This module provides access to some variables used or maintained by the interpreter and to functions that interact strongly with the interpreter. re This module provides regular expression matching operations similar to those found in Perl. random This module implements pseudo-random number generators for various distributions. time This module provides various time-related functions. selenium Selenium automates browsers. beautifulsoup4 Beautiful Soup is a Python library for pulling data out of HTML and XML files. pyautogui PyAutoGUI is a cross-platform GUI automation Python module for human beings. Used to programmatically control the mouse & keyboard. ChromeDriver WebDriver is an open source tool for automated testing of webapps across many browsers. • 설명은 공식 홈페이지의 설명 인용(www.python.org, Beautiful Soup, Selenium, PyAutoGUI, ChromeDriver) • 실제 사용 방법은 코드에서 설명 PyAutoGUI https://github.com/asweigart/pyautogui ChromeDriver https://sites.google.com/a/chromium.org/chromedriver/home
  • 6. 전체 코드 2 1 1 ▪ download_cyworld() 함수 1. 백업 대상 연도를 매개 변수로 받음 2. 크롬 브라우저 시작 3. 싸이월드 로그인 4. 백업 대상 연도의 모든 포스트 리스팅 5. 모든 포스트를 html 파일로 저장 2 ▪ 스크립트 시작점 1. 스크립트가 정상적으로 실행이 되었을 경우 2. 필요한 모듈을 임포트하고 3. download_cyworld() 함수로 해당 연도를 매개 변수로 전달하여 실행
  • 7. 코드 설명 #1 라인 설명 86 ▪ cyworld.py라는 스크립트가 아래의 **와 같이 독립적으로 실행될 때만 86번 라인 이후의 코드가 바로 실행됨 ▪ 즉, 다른 스크립트에서 모듈로 임포트되는 경우에는 바로 실행되지 않음 ** C:>cyworld.py 2009 88~100 ▪ 표준 및 추가 라이브러리 임포트 ▪ BeautifulSoup은 “as”로 임포트 하였기 때문에, BS라는 별칭으로 사용됨 ▪ selenium expected_conditions는 EC로 사용됨 102~106 ▪ cyworld.py 스크립트로 전달된 매개 변수의 개수가, 2개 로 올바르게 입력된 경우, 매개 변수를 변수로 할당하고 download_cyworld()함수 호출 ▪ 아래의 **와 같이 실행된 경우, len(sys.argv) == 2가 됨 • sys.argv[0]=cyworld.py • sys.argv[1]=2009  input_year로 할당 ▪ 즉, download_cyworld(2009)의 형태로 함수 호출 ** C:>cyworld.py 2009 107~110 ▪ cyworld.py 스크립트로 전달된 매개 변수의 개수가 2개가 아닌 경우에는 안내 메시지 출력
  • 8. 코드 설명 #2 라인 설명 4 ▪ input_year를 매개 변수로 받는 함수 정의 6 ▪ ChromeDriver 설치(압축 해제) 경로를 명시 7, 8 ▪ 웹 드라이버를 이용해 크롬 브라우저를 실행시키고 cyworld 객체로 생성한 후에, 창을 최대화 함 ▪ 크롬 브라우저가 실행이 되면, 소프트웨어에 의해 제어됨 이 표시됨 • “코드 설명 #2 - 부가설명 #2” 참조 11 ▪ 브라우저에서 로그인 페이지를 로딩 12, 13 ▪ 로그인 정보(uid, upw)를 브라우저로 전달 14 ▪ “로그인” 버튼을 클릭 15 ▪ “내싸이홈가기”가 클릭이 가능한 상태가 될 때까지 대기 16 ▪ “내싸이홈가기”를 클릭 17 ▪ time 모듈을 사용하여 5초간 대기 ▪ 실제 사람처럼 웹 브라우저를 조작하므로, 웹 페이지가 정상적으로 로드 될 때 까지, WebDriverWait()와 time.sleep()으로 적정한 대기 코드가 필수 20~26 ▪ 11~17 라인과 비슷한 방식으로 브라우저 조작 ▪ 특정 연도의 포스트 리스트 첫 페이지를 가져옴 ▪ sDate, eDate에 ’00’이 붙는 것은, 싸이월드 특성 • cyworld.find_element_by_xxxxxxxx로 시작하는, 모든 코드는 “코드 설명 #2 - 부가설명 #1” 참조 • 브라우저 조작은 “코드 설명 #2 - 부가설명 #2” 참조
  • 9. 코드 설명 #2 - 부가 설명 #1(웹 ELEMENT 찾기) 1. 브라우저에서 대상 요소 우 클릭  검사 2. Elements 창에서 해당 요소를 우 클릭 3. 필요한 요소를 복사 해서 사용 ▪ 코드에서 아래와 같은 모든 라인은 이 방법을 통하여 찾음 ▪ id의 경우 Elements 창에서 확인 가능 • cyworld.find_element_by_id • cyworld.find_element_by_xpath • cyworld.find_element_by_css_selector ▪ xpath: XML Path  참고: https://ko.Wikipedia.org/wiki/XPath ▪ css selector: CSS Selector  참고: http://www.nextree.co.kr/p8468 ▪ 웹 페이지에서 가장 unique하고 변경이 적을 만한 요소의 사용을 권장
  • 10. 코드 설명 #2 - 부가 설명 #2(브라우저 조작) 라인 11: 로그인 페이지 라인 12: uid 라인 13: upw 라인 14: //*[@id="tab_cont1"]/div/input 라인 15, 16: //*[@id="loginbox"]/ul/li[1]/a 라인 20: //*[@id="all"] 라인 21, 22: //*[@id="allArea"]/div/ul/li[2]/label/span 라인 23, 24: sDate, eDate 라인 25, 26: //*[@id="allArea"]/div/div/button 라인 7: 웹 드라이버로 제어되는 크롬 브라우저 실행, cyworld 객체
  • 11. 코드 설명 #3 라인 설명 29~37 ▪ 20~26 라인을 통해 2009년 포스트의 첫 페이지가 표시됨 ▪ 그러나, 모든 포스트가 아닌 최근 24개만 표시가 됨 ▪ 페이지 하단의 “+” 버튼으로 모든 포스트의 목록을 표시 ▪ “+” 버튼 누르기는 xpath로는 원하는 구현이 되지 않아 css selector 사용 ▪ while 구문으로 “+”가 나타나면 계속 클릭 ▪ 더 이상 “+“ 버튼이 나타나지 않아, selenium exception이 발생하면 메시지를 표시하고 pass 시킴 40~43 ▪ cyworld 객체의 page_source를 beautifulsoup를 이용하 여 파싱하고 soup 객체 생성 ▪ 각 포스트의 url들을 저장할 빈 post_urls set 생성 45~48 ▪ soup 객체에서 포스트 URL이 담긴 “postSection” 검색 ▪ 검색된 “postSection”내에서, 간단한 정규 표현식으로 “/home/25967997/post/”로 시작하는 html “a” tag만 검색 하여 link로 전달 ▪ link에서 “href” 속성의 값(URL)만 link_url로 생성 ▪ link_url로 각 포스트의 전체 URL을 생성 ▪ post_urls set에 각 포스트의 전체 URL을 추가 51~53 ▪ 해당 연도의 전체 포스트 개수가 표기된 “제목“ 출력 ▪ 실제로 post_urls set에 저장된 post_url의 개수 출력 • 브라우저 조작과 변수는 “코드 설명 #3 - 부가 설명 #1, #2” 참조
  • 12. 코드 설명 #3 - 부가 설명 #1(브라우저 조작) 라인 31, 33: #divMoreBtn > button ▪ soup 객체: 아래의 항목들을 검색하고 참조할 수 있음 • postTitle • postSection • 개별 포스트의 URL • 개별 포스트의 subject • 등등등
  • 13. 코드 설명 #3 - 부가 설명 #2(45~48 라인 변수) ▪ 라인 45: link <a href="/home/25967997/post/4A512E18280003187AFA6401" onclick="Post.ClickView('4A512E18280003187AFA6401');return false;"> <span class="date">7.6</span> <h3 class="subject">산책로 입구</h3> <div class="data"><figure alt="산책로 입구 " class="postImage" style="background- image:url('http://cythumb.cyworld.com/269x269/cyimg25.cyworld.com/common/file_down.asp?redirect=%2F250012%2F2009%2F7%2F6%2F62%2F200907060 74949_25967997.jpg');"></figure> </div> </a> ▪ 라인 46: link_url /home/25967997/post/4A512E18280003187AFA6401 ▪ 라인 47: post_url http://cy.cyworld.com/home/25967997/post/4A512E18280003187AFA6401 ▪ 라인 48: post_urls http://cy.cyworld.com/home/25967997/post/4A512E18280003187AFA6401 http://cy.cyworld.com/home/25967997/post/4A512ECC3DC003187AFA6401 http://cy.cyworld.com/home/25967997/post/4A512F08920003187AFAA801 http://cy.cyworld.com/home/25967997/post/4A512C38014003187AFA6401 ……………
  • 14. 코드 설명 #4 라인 설명 56, 57 ▪ html 파일 저장 폴더인 save_dir 정의 ▪ 포스트 URL을 저장할 텍스트 파일 post_list 정의 59, 60 ▪ save_dir이 없으면, 폴더 생성 62, 63 ▪ post_list가 없으면, 쓰기 모드로 신규 파일 생성 65 ▪ post_urls에서 각 URL을 하나씩 post로 전달 66 ▪ 브라우저에서 해당 페이지를 로딩 67 ▪ 페이지 하단의 “댓글 박스”가 로딩될 때까지 대기 ▪ 사진이 많아서 로딩이 오래 걸릴 경우를 대비하여 타임아 웃을 보다 길게 설정 68 ▪ 해당 포스트의 “등록일시”를 post_date로 생성 69 ▪ save_dir과 post_date를 슬라이싱하여 입력 파일 명 생성 ▪ random 함수는 제목이 없는 포스트의 경우, 파일명이 중 복되어 제대로 저장되지 않는 경우가 발생. 이를 방지하 기 위하여 저장 파일명에 임의의 정수를 추가 70 ▪ CYWORLD_XXXX.txt에 저장될 파일명과 URL을 기록 72~79 ▪ pyautogui로 웹 브라우저의 “우 클릭" “다른 이름으로 저장”  “파일명 입력”  “저장”을 구현 ▪ 브라우저의 “다른 이름으로 저장” 기능은, OS가 제어를 하는 영역이라 selenium(브라우저)에서는 제어 불가능 82, 83 ▪ post_list(CYWORLD_XXXX.txt) 및 웹 브라우저 닫기 • 브라우저 조작과 변수는 “코드 설명 #4 - 부가 설명 #1” 참조
  • 15. 코드 설명 #4 - 부가 설명 #1(브라우저 조작 및 변수) 라인 67: //*[@id="inputWrap123456"]/textarea 라인 68: #postData > div.postInfo > ul > li.date > p ▪ 라인 68: post_date 2009.07.06 08:42 (업로드 2009.07.06 08:42) ▪ 라인 69: save_file_name C:UsersSeungYongDesktop200907.06_39_ • 실제로 저장될 파일명은 save_file_name + “해당 포스트의 제목“ • 예를 들어 제목이 “제주도”라면 아래와 같은 파일명으로 저장됨 • C:UsersSeungYongDesktop200907.06_39_제주도 ▪ C:UsersSeungYongDesktop2009CYWORLD_2009.txt 파일의 내용
  • 16. 코드 스타일 점검 ▪ 코드의 문법 및 스타일 점검을 위하여 pycodestyle 사용 ▪ pycodestyle은 기존의 pep8의 이름이 변경된 것임 ▪ 여러 항목의 코드 스타일에 대한 체크를 해 줌 ▪ E501: 일반적으로 79 컬럼 내에 코드를 작성할 것을 권고하는 에러 • C:UsersSeungYong>pip install pycodestyle • C:UsersSeungYong>pycodestyle cyworld.py
  • 17. 고려 사항 1. 이 스크립트는 다양한 경우의 예외 또는 에러가 발생할 수 있으나, 이에 대한 오류 처리 코드가 없음 ▪ 모든 오류를 코드로 처리하는 것보다, 단순 재실행하는 방법이 보다 생산성이 높을 것으로 생각 2. 10회를 수행하였을 때 PC, 네트워크, 서버등의 다양한 원인으로 2~3회 이상 실패할 수 있음 ▪ 이러한 경우, 바탕화면의 폴더를 지우고 재실행 3. 웹 브라우저를 직접 실행하는 형태여서, 스크립트를 실행하면 PC를 사용할 수 없음 ▪ pyautogui 모듈의 경우, 마우스 및 키보드를 직접 제어하기 때문에 사용자의 개입시에 오류 발생 ▪ 스크립트를 수행하고 취침하는 방식을 권장 ▪ PhantomJS를 이용하여 headless로도 시도를 하여 보았으나, 제대로 수행되지 않음(실력의 한계) 4. 백업 수행 속도는 환경에 따라 다르나, 분당 평균 6개 포스트~10개 정도 5. 실행시에 아래와 같은 에러는 브라우저, selenium, ChromeDriver등 버전에 따라 나오기도 하고 안 나오기도 함 ▪ 그러나, 싸이월드 포스트를 html 파일로 백업하는 것에는 지장 없음 http://phantomjs.org/