파이썬 업무에서 가장 많이 활용하는 분야는 데이터 수집, 데이터 전처리와 분석, 머신러닝, 딥러닝, 데이터 시각화 등이다.
웹에서 데이터를 수집하는 코드를 작성
데이터를 분석하는 단계는 데이터 수집과 전처리, 데이터 분석과 시각화 단꼐로 이루어진다.
일반적으로 검색엔진은 자료수집, 인덱싱, 검색의 3단계로 구성되어 있는데, 크롤러가 웹페이지들을 수집하면 검색 시에 보다 빨리 찾기 위해서 인덱서가 수집한 결과들을 정리해서 보관하고, 그 후 사용자의 입력이 들어오면 결과를 찾아서 보여준다. 이러한 검색엔진으로 구글이 성장헸고, 지금은 세계 곳곳에 데이터 센터를 만들어 두고, 웹 크롤러를 통해 수집한 데이터들을 저장하는 등의 작업을 수행한다.
여기서 크롤링(Crawling)이란 웹페이지의 연결된 링크(하이퍼링크)를 돌아다니면서 웹페이지를 다운로드하는 작업을 의미한다. 즉, 프로그램이 정기적으로 웹사이트를 돌며 정보를 추출하는 기술이다. 크롤링을 통해서 주로 HTML 형태의 데이터들을 수집한다.
더불어 스크래핑(Scraping)이란 웹 사이트의 데이터들을 수집(긁어와서)해서 필요한 내용을 추출(parsing)하는 것을 의미한다. 잡지나 신문의 특정 부분을 잘라내는 것을 스크랩이라고 하듯이 스크래핑은 웹사이트상에서 원하는 부분에 위치한 정보를 프로그램으로 하여금 자동으로 추출하여 수집하는 기술이다. 어떤 웹페이지에서 원하는 데이터를 특정 패턴이나 순서 등으로 추출하여 데이터를 가공하는 것을 파싱(parsing)이라고 한다. 스크래핑은 크롤링과 파싱을 하는 것이다. 크롤링도 일종의 스크래핑 기술이라고 할 수 있다.
대부분의 크롤링 라이브러리들과 스크래핑 라이브러리들이 웹페이지의 데이터를 수집해서 원하는 부분을 파싱하는 기능들을 포함하고 있기 때문에 굳이 크롤링과 스크래핑이라는 용어를 구분해서 사용할 필요는 없다.
크롤링 프로그램을 작성하기 위해서는 웹사이트의 동작 방식을 이해하고, 크롤링을 수행하는 파이썬 라이브러리들을 알아야 한다. 웹사이트의 동작 방식은 웹클라이언트(브라우저)와 웹서버가 통신할 때 사용하는 HTTP 프로토콜의 요청과 응답, 웹페이지의 구성인 HTML 구조와 태그, CSS나 자바스크립트 등을 이해해야 한다.
먼저 웹의 동작 방식과 프로토콜, HTML과 CSS에 대해 알아보고, 파이썬 크롤링 라이브러리를 살펴본다.
통신 프로토콜 또는 통신 규약은 컴퓨터나 원거리 통신 장비 사이에서 메시지를 주고받는 양식과 규칙 체제다. 서로 다른 기기의 컴퓨터들이 통신하기 위해서는 네트워크에 접속하는 방법, 주고받는 데이터으 ㅣ형식, 데이터를 변환하는방식 등이 모두 다르기 때문에 원활하게 데이터를 주고받고 통신을 하기 위해서는 미리 통신 규칙과 약속을 정해서 사용해야 한다. 이러한 규칙을 프로토콜이라고 한다.
HTTP(HyperText Transfer Protocol)은 클라이언트와 서버 사이에 이루어지는 요청/응답(request/response) 프로토콜이다. 클라이언트인 웹브라우저가 HTTP를 통하여 서버에 웹페이지나 기타 정보를 요청하고, 서버는 이 요청에 응답하여 필요한 정보를 해당 사용자에게 전달한다.
Web Client (Web browser) -http request-> Web Server
Web Client (Web browser) <-http response- Web Server
http:// naver.com( :80 /docBase /indexFile)?name=value&name=value&...
protocol host address port 문서를 공급할 directory 보여줄 문서 Query String(쿼리문자열)
host address : domain address, ip address
indexFile : web server 혹은 web application의 설정 file 등록
Query String : html의 form tag를 사용하여 사용자가 선택, 입력, 클릭 등의 작업 수행하고, 데이터들을 서버로 전송
쿼리 문자열은 업거나 url 창에 안 보이기도 한다.
HTTP Get, Post에 따라서 다름 (전송 방식)
HTML(Hyper Text Markup Language : 하이퍼 텍스트 마크업 언어) 웹페이지 표시를 위해 개발된 마크업 언어(markup Language)다. 마크업 언어는 태그 등을 이용하여 문서나 데이터의 구조를 명시하는 언어를 의미한다.
HTML은 제목, 단락, 목록 등과 같은 본문을 위한 구조적 의미를 나타내는 것뿐만 아니라 링크, 인용과 그 밖의 항목으로 구조적 문서를 만들 수 있는 방법을 제공한다. HTML은 웹 페이지 콘텐츠 안의 꺾쇠괄호에 둘러싸인 태그로 되어 있는 HTML 요소 형태로 작성한다. HTML은 웹 브라우저와 같은 HTML 처리 장치의 행동에 영향을 주는 자바스크립트, 본문과 그 밖의 항목의 외관과 배치를 정의하는 CSS 같은 스크립트를 포함하거나 불러올 수 있다.
웹페이지를 직접 제작하는 경우에는 HTML의 모든 태그를 알아야 하지만, 크롤링이 목적이라면 주요 태그를 중심으로 익히고, 기타 태그들은 필요한 경우에 찾아본다.
HTML 문서를 구성하는 기본 요소(Element : 엘리먼트)들을 소개한다. HTML 요소(Element : 엘리먼트) 는 시작 태그(start tag)에서 종료 태그(end tage)까지의 모든 것을 의미한다.
<h1>안녕하세요.</h1>
<h1>은 시작 태그이고, 요소의 내용(콘텐츠)은 안녕하세요. 라는 텍스트(문자열)이며, </h1>은 종료 태그다. 태그명 앞에 /(슬래시)를 붙이면 종료 태그가 된다.
모든 태그는 시작 태그와 함께 속성(Attribute)을 사용할 수 있는데, 속성='값' 형식으로 사용한다.
<a href='https://www.python.org/'>welcome to Python</a>
위 요소에서는 href='https://www.python.org/' 부분이 속성과 값이다.
일부 HTML 요소에는 내용(콘텐츠)과 종료 태그가 없는 빈 요소들도 존재한다. 빈 요소는 예를 들어 <br> 태그 등이 있다.
요소와 태그는 혼용되는 경우가 많은데, HTML 문서만을 다룰 때는 크게 상관없으나 CSS 선택자나 파이썬 라이브러리 등에서는 요소라는 표현을 중요하게 사용한다.
단순하게 웹 페이지의 HTML 태그들을 분석할 때는 태그라는 표현을 사용하고, CSS 선택자나 파이썬 라이브러리에서는 요소라는 표현을 사용한다.
<html>을 시작으로 태그들은 부모(parent)와 자식(child) 관계로 계층화되어 있다. 자식 태그는 부모의 시작 태그 다음에 나오며, 부모의 종료 태그 이전에 종료 태그가 나온다.
<html> - 문서의 루트 태그이며, 하나의 문서에서 루트 태그는 하나만 허용된다. 모든 html 태그는 <html\<의 자식 태그이다.
<head> - 문서의 제목, 스타일 파일 연결, 자바스크립트 삽입을 위한 태그들을 포함한다. 여러 자식 태그들을 포함한다. 문서 내에서 한 번만 사용되며, head 의 내용은 웹 페이지에 표시되지 않는다. 주로 페이지 설명 등을 하는 메타 데이터를 포함한다.
<body> - 문서의 본문을 나타내는 태그이며, 문서 내에서 한 번만 사용된다. 우리가 살펴볼 대부분의 태그는 body의 자식 태그다. 웹 페이지에서 보여지는 화면은 body 태그와 그 자식 태그들의 결과이다.
크롤링할 때 제일 중요한 것은 웹페이지가 어떻게 분할되어 있는지 레이아웃(구조)를 파악하는 것이다. 웹페이지는 눈에 보이지는 않지만 다양한 행과 열들로 구성된다.
화면 분할할 때 주로 사용되는 HTML 태그
목록을 정의할 때는 다음과 같은 태그들을 사용한다. 뉴스기사, 카페나 블로그 글 목록, SNS 글 목록, 주식 현황, 상품 목록, 상품의 가격비교, 주문 목록 등에서 많이 사용한다.
HTML은 문서와 문서를 연결할 수 있는데, 특정 링크를 클릭하면 해당 페이지로 이동한다. 이동하고 싶은 페이지가 있다면 <a> 태그를 사용하여 하이퍼 링크를 지정한다. <a> 태그의 href 속성이 중요한데 속성의 값으로 이동할 페이지의 주소 URL을 명시한다.
<a href='이동할 url'> 보여지는 텍스트 </a>
테이블(표)를 만들 때는 다음 태그를 사용한다. 테이블 관련 주요 태그들은 다음과 같고, 이외에도 <table>의 자식 태그로 여러 태그가 존재한다.
<form> 태그를 정의하면, 사용자가 값을 입력하거나 항목을 선택하거나 버튼 등을 클릭하는 행동들을 할 수 있으며, 사용자가 입력한(혹은 선택한) 값들을 쿼리 문자열을 통해 서버로 전송된다. 우리가 웹페이지에 로그인할 때 아이디나 패스워드를 입력하고 로그인 버튼을 클릭하는 것들은 모두 <form> 태그를 통해 이루어진다.
<form method=post action=''>
<input type='text' name=''>
</form>
CSS(Cascading Style Sheets :. 캐스케이딩 스타일 시트)는 W3C의 표준이며, 웹페이지의 레이아웃과 스타일을 정의할 때 사용된다. CSS는 마크업 언어가 실제 표시되느 방법을 기술하는 언어로 HTML 구조는 그대로 두고 CSS 파일만 변경해도 다른 웹사이트처럼 보이게 할 수 있다.
마크업 언어가 웹 사이트의 몸체를 담당한다면 CSS는 옷과 액세서리처럼 꾸미는 역할을 담당한다고 할 수 있다.
CSS 선택자(CSS Selector)는 CSS 규칙을 적요알 요소를 정의한다. CSS 선택자를 사용하여 HTML 요소들을 접근하고 레이아웃과 스타일을 정의한다. 크롤링 프로그램을 작성할 때, 크롤링한 웹페이지에서 원하는 부분을 선택하기 위해서는 CSS 선택자를 이용한다.
F12
우클릭 Copy -> Copy element : 해당 소스 복사
이외에도 다양한 크롤링 라이브러리가 있다.
셀레늄(selenium)은 다양한 브라우저를 자동으로 좆가하는 도구다. 원래 웹애플리케이션 자동 테스트 도구로 개발되었지만, 최근에는 웹페이지를 크롤링하기 위해 많이 사용된다.
셀레늄을 사용하면 마치 사용자가 컴퓨터 앞에 앉아서 웹브라우저를 직접 조작하는 것처럼 자동으로 브라우저를 제어해서 입력, 선택, 이동 등이 가능하다. 또한 자바스크립트를 실행할 수 있는 크롤러를 만들 수 있다.
다른 크롤링 라이브러리들을 사용한다면, 웹사이트에서 버튼 등을 클릭하거나 사용자의 입력을 통하여 얻을 수 있는 데이터에 접근하는 것에 한계가 있고, 자바스크립트를 사용하여 조건에 따른 데이터 접근 등에 한계가 있다. 이러한 작업을 하려면 셀레늄을 사용해야 한다.
셀레늄은 파이썬 이외에도 다양한 언어에서도 사용이 가능하다.
셀레늄을 사용하려면 셀레늄 웹 드라이버(Web Driver)가 필요하다. 웹 드라이버는 웹프라우저를 제어해주고, 셀레늄 라이브러리에서 호출해서 사용한다. 셀레늄 라이브러리가 사용하는 웹브라우저라고 봐도 무방하다. 웹 드라이버를 활용하면 다양한 OS, 다양한 웹브라우저(동일 브라우저의 다양한 버전 포함)를 조작할 수 있다.
Web Browser(Chrome) <-> Web Driver(OS, Browser의 버전별로 download) <-> Python selenium 라이브러리 사용
셀레늄 라이브러리에서 직접 브라우저를 제어하지 않고, 중간에 웹 드라이버를 두는 이유는 다음과 같다.
우리가 사용하는 OS는 Windows, Mac, Linux 등으로 다양하며 각 OS 내부 구현 코드가 모두 다르다. 웹 브라우저도 Firefox, Internet Explorer, Safari, Opera, Edge 등으로 다양하며, 각 브라우저도 버전별로 내부 구현 코드도 다르다. 따라서 셀레늄 라이브러리에서는 OS와 웹 브라우저별로 다른 코드들을 작성해야 한다.
어떤 웹브라우저를 사용하든지 웹 드라이버만 변경해주면, 파이썬 코드에는 OS 및 브라우저와는 무관하게(독립적으로) 동일한 방식으로 동일한 함수를 사용하는 크롤링 코드를 작성할 수 있다.
개발자가 해야 하는 거은 OS와 브라우저 버전에 맞는 웹 드라이버를 다운받고, 파이썬 코드 내에서 브라우저의 이름의 객체를 생성하기만 하면 된다.
먼저 크롬 브라우저의 버전을 확인한다. 크롬 브라우저 상단 오른쪽 끝의 점 3개(Chrome 맞춤설정 및 제어) 부분을 클릭하고, 도움말 -> chrome 정보 메뉴를 클릭하여 크롬 버전을 확인한다.
chromedriver.storage.googleapis.com/index.html
맞는 버전 없으면 가장 최신 거 114. ~
들어가서 chromedriver win32.zip 다운로드 -> 압축 해제
exe 실행하는 거 아니고 셀레늄에 의해서 실행됨 더블 클릭 X
파일 두개 다 복사해서 파이썬 설치돼있는 홈 디렉토리(PATH로 지정된 디렉터리)에 붙여넣기
그럼 자동으로 읽혀짐

pip show selenium
셀레늄으로 크롤링하기
selenium은 라이브러리명과 모듈명이 동일하다. selenium 모듈의 클래스와 함수 등을 알아보고 파이썬 크롤링 프로그램을 작성하면 된다. 크롤링하기 위해서 제일 먼저 해야 할 일은 웹 드라이버 구현 클래스로부터 객체를 생성하는 것이다.
selenium, webdriver 모듈은 웹 드라이버 구현 클래스들을 제공한다.
https://selenium-python.readthedocs.io/index.html
7. WebDriver API
from selenium import webdriver
# chrome 객체 생성
driver = webdriver.Chrome()
# crawling
driver.get('http://www.python.org')
이 때 앞에서 다운받은 웹 드라이버가 PATH에 등록된 디렉터리에 없거나 드라이버의 버전이 브라우저와 맞지 않은 경우에 에러가 발생할 수 있다.
만약 직접 드라이버의 위치를 지정하고 싶은 경우
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
service = Service(executable_path='C:/python/Chromedriver.exe')
driver = webdriver.Chrome(service=Service)
실행 파일 위치는 다운로드 받은 곳으로 설정
이렇게 웹페이지를 크롤링한 후에는 원하는 요소를 찾아야 한다. 셀레늄 공식 문서에서도 요소라는 표현이 사용된다. 웹페이지에서 요소를 찾고자 한다면, 다음 두 함수를 사용하낟.
find_element() : 최초로 발견한 요소 하나만 반환한다.
find_elements() : 내부의 모든(여러) 요소를 추출하여 리스트로 반환한다.
find_element() 함수는 매개변수가 중요하다. By.속성 형태로 매개변수를 넘기는데, 이 속성으로 원하는 요소를 찾을 수 있다.
find_element(By.ID, 'id') : id 속성으로 'id'에 해당하는 요소를 하나 추출한다.
find_element(By.NAME, 'name') : name 속성으로 'name'에 해당하는 요소를 하나 추출한다.
find_element(By.CLASS_NAME, 'class name') : class 속성으로 'class name'에 해당하는 요소를 하나 추출한다.
find_element(By.CSS_SELECTOR, 'css selector') : CSS 선택자로 요소를 하나 추출한다.
find_element(By.TAG_NAME, 'tag name') : 태그 이름이 'tag name'에 해당하는 요소를 하나 추출한다.
find_element(By.LINK_TEXT, 'link text') : 링크 텍스트로 요소를 추출한다.
find_element(By.PARTIAL_LINK_TEXT, 'partial link text') : 링크의 자식 요소에 포함되어 있는 텍스트로 요소를 하나 추출한다.
find_element(By.XPATH, 'xpath') : xpath를 지정해 요소를 하나 추춣한다.
selenium.webdriver.common.by.By 클래스를 import 한 후 사용
find_element() 함수와 동일한 방식으로 find_elements()를 사용할 수 있다. find_element()는 하나의 결과만을 가져오고, find_elements()는 여러 개의 결과를 가져온다.
셀레늄에는 텍스트 상자, 버튼 클릭 등 다양한 요소를 조작할 수 있는 함수가 있다. 이런 함수를 통해 사용자가 브라우저에 값을 입력할 수도 있고, 요소를 선택하거나 클릭하는 등의 작업을 할 수 있다.
clear() : 글자를 입력할 수 있는 요소의 글자를 지운다.
click() : 요소를 클릭한다.
send_keys(value) : value로 주어진 키를 입력한다.
submit() : 입력 양식을 전송한다. form 태그의 submit 기능이다.
get_attribute(name) : 요소의 속성 중 name에 해당하는 속성의 값을 추출한다.
execute_script() : 자바스크립트 코드를 실행한다.
<a href='~'>내용</a>
a 태그 값 가져오기
a.get_attribute('href')
send_keys(value) 함수는 텍스트뿐만 아니라 특수 키 등도 입력할 수 있다. 예를 들어 Enter 키나 방향키 Shift 키, ALT, Control 키, F1 ~ F12 키 등을 입력할 수 있다. 특수 키 입력을 위해서는 selenium.webdriver.common.keys.Keys 를 import 하고 사용한다. 아래는 Enter 키를 입력하기 위한 코드다. RETURN 대신 ENTER를 사용해도 된다. 키값은 모두 대문자다.
from selenium.webdriver.common.keys import Keys
send_keys(Keys.RETURN)
웹 페이지를 크롤링할 때 중요한 것은 웹 페이지가 로딩될 때까지 기다렸다가 원하는 요소들을 찾는 것이다. 만약 웹 페이지가 로딩되지 않았다면 element(요소)를 찾을 수 없다는 에러가 발생한다. 페이지 로딩을 기다리는 방식은 명시적 기다림과 묵시적 기다림 두 가지 방식이 있다.
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
element = WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.ID, 'value'))
)
튜플로 전달
from selenium import webdriver
driver = webdriver.Chrome()
driver.implicitly_wait(10) # 초 단위 지정
파이썬 표준 라이브러리의 time 모듈 사용
import time
time.sleep(10) # 초 단위 지정
대부분의 크롤링 코드에서는 명시적 기다림과 묵시적 기다림을 함께 사용한다.