일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |
- 데이터프레임
- seaborn
- 크롤링
- DataFrame
- numpy
- XOR게이트
- 머신러닝
- 판다스
- AND게이트
- pandas
- Perceptron
- ubuntu
- 데이터크롤링
- OR게이트
- Deeplearning
- 선형회귀
- 데이터시각화
- python
- 우분투
- 달의조각
- 파이썬
- 비지도학습
- NAND게이트
- 리눅스
- 딥러닝
- 데이터분석
- 로지스틱회귀
- 퍼셉트론
- 씨본
- linux
- Today
- Total
Charming ['ㅡ'] Ham !
셀레니움을 통한 브라우저 원격제어, 데이터 크롤링 본문
크롤링을 활용하여 로그인하기¶
로그인하기¶
로그인을 위해서 쿠기, 세션, 캐시에 대한 개념이 필요하다. 로그인 시 HTTP 통신은 쿠키를 보내거나 세션 ID 를 기록하는 작업을 수행하게된다.
먼저 쿠키와 세션에 대해 알아보자.
-
쿠키는 HTTP 헤더를 기반으로 이루어지는 데이터이다. "클라이언트 로컬"에 저장되는 Key-Value쌍의 작은 데이터 파일이며, 방문자가 데이터를 원하는 형태로 변경할 수 있고, 저장소는 브라우저 즉, 클라이언트가 가지고 있다.
-
세션도 쿠키를 이용해 데이터를 저장한다. 하지만 쿠키에는 방문자 고유 ID같은 정보만 저장하고 실제로 모든 데이터는 웹 서버에 저장하며, 서버에 데이터를 저장하므로 쿠키와는 다르게 저장할 수 있다.
쿠키와 세션은 저장 위치
와 보안
, Lifecycle
, 속도
에서 차이점을 알 수 있다.
쿠키는 로컬에만, 세션을 로컬과 서버 2곳에 저장이된다.
또한 쿠키는 탈취와 변조가 가능해 보안에 취약한 반면, 세션은 ID 값만 가지고 있으며, 서버에도 저장이 되므로 상대적으로 안전한다.
Lifecycle 측면에서 쿠키는 브라우저를 종료해도 파일로 남아있는 반면, 세션은 브라우저 종료 시 삭제된다.
속도 측면에서 쿠키는 파일에서 읽기 때문에 상대적으로 빠르고, 세션은 요청마다 서버에서 처리하므로 상대적으로 느린 속도를 가지고 있다.
로그인 과정¶
네이버 로그인을 가정하에 예를 들면,
-
로그인 버튼 클릭
-
F12를 눌러서 개발자 도구로 들어간 뒤
-
Network 탭을 선택.
-
Preserve log를 선택.
-
Doc탭을 선택.
하는 과정을 통해 진행된다. 이에 사용된 로그를 살펴보면, POST 메소드로 요청을 하고, Headers 를 살펴보면 id 와 pw 를 전달한다.
이제 위 과정을 코드로 구현해보자. 로그인을 해서 네이버 별명(닉네임) 을 가져오는 것을 목표로 한다.
from bs4 import BeautifulSoup
import requests
#세션 생성하기
session = requests.session()
#로그인하기
log_info = {'id':'', #여러분의 ID와 PW를 입력
'pw':''}
url = 'https://nid.naver.com/nidlogin.login'
response = session.post(url, data=log_info)
#마이페이지 접근하기
url_mypage = 'https://nid.naver.com/user2/help/myInfo.nhn?lang=ko_KR'
response = session.get(url_mypage)
#Soup객체 생성
soup = BeautifulSoup(response.text, 'html.parser')
#마이페이지에 별명 가져 오기
soup.find('span')
<span>본문으로 바로가기</span>
위 코드에서 자신의 계정 정보를 입력하고 실행을 해보더라도 실패할 것이다. 만약 이렇게 로그인 후 개인정보를 가져온다면 보안에 매우 취약하기 때문이다.
위 크롤링은 PHP 서버로 로그인을 할 때 사용할 수 있는 코드로 로그인 요청 메소드로 Request URL을 보낼 때 "xxxxxx.php"형식으로 된 웹 페이지에서만 가능한 방식이다.
브라우저 제어를 통한 크롤링¶
웹페이지에서 데이터를 모으기 위해서 로그인이 필수인 페이지들도 있다. 하지만 위에서 로그인은 보안 상의 문제로 접근이 막혀있는데 이를 위해 브라우저를 직접 자동으로 제어하여 로그인을 하고, 원하는 데이터를 찾아 모으는 크롤러를 만들 수 있는 라이브러리가 만들어졌는데, 바로 Selenium (셀레니움)
이다.
Selenium¶
셀레니움은 원래 웹 앱을 테스트트하는 웹 프레임 워크이다. webdriver API 를 통해 브라우저를 제어하며, 때문에 자바스크립트에 의해 동적으로 생성되는 사이트 데이터도 크롤링 할 수 있다. 동적 생성되는 사이트란 쉽게 생각해서 구글이나 네이버, 카카오에서 제공되는 지도를 통핸 위치 데이터와 같은 것이다.
- 셀레니움 설치
- 브라우저 드라이버 다운
- 브라우저 드라이버 설치 경로에 카피
- 셀리니움, 브라우저 제어를 통한 크롤링
순으로 브라우저 제어를 진행하게 된다.
1.
$ pip install selenium
# 설치에 문제가 있을 시, 다음과 같이 conda로 설치 진행
$ conda install selenium
먼저 위와 같이 셀레니움을 설치하자.
2.
이제 브라우저 드라이버를 설치해야 한다. 각 브라우저들의 드라이버를 다운받을 수 있는 링크는 다음과 같다.
Chrome : https://sites.google.com/a/chromium.org/chromedriver/downloads
Edge : https://developer.microsoft.com/en-us/microsoft-edge/tools/webdriver/
Firefox : https://giyhub.com/mozilla/geckodriver/releases
Safari : https://webkit.org/blog/6900/webdriver-support-in-safari-10/
여기에서는 크롬을 통해 브라우저를 제어하기 위해 크롬드라이버를 다운 받도록한다.
해당 브라우저의 드라이버를 다운 받기위해서는 해당 브라우저의 버전와 일치하는 버전의 드라이버를 다운받야야한다.
크롬의 경우 도움말ㅇ서 크롬 정보에 들어간 후 버전을 확인하고, 해당 버전에 맞는 드라이버를 다운 받도록 하자.
3.
브라우저 드라이버를 다운 받고, 원하는 경로에 옮긴다. 이 드라이버는 일종의 API 로 사용하기 위해 경로가 필요하므로 필수적으로 기억을 해 놓자.
$ mkdir -p ~/aiffel/lib
$ cd ~/다운로드
$ unzip chromedriver_linux64.zip
$ mv chromedriver ~/aiffel/lib
4.
셀레니움을 이용해 공공데이터를 크롤링 해보자.
크롤링은 URL 다운로드, 해당 URL을 셀레니움을 통한 브라우저 제어(css 선택자 선택), 다운받은 csv 파일 확인 의 과정을 거친다.
crawling_urls = {
"산과공원": "https://data.seoul.go.kr/dataList/OA-12962/S/1/datasetView.do",
}
# 필요 라이브러리 가져오기
import requests
from selenium import webdriver
import time
import pandas as pd
import os
import os.path
import glob
셀레니움을 통해 브라우저 제어하기¶
필요한 데이터, 여기에서는 다운 가능한 링크의 위치가 어디에 있는지 확인을 하고 이를 클릭하여 다운받아야 한다.
이를 위해서는 css 선택자를 잘 선택하는 것이 중요하다. 해당 웹페이지에서 F12
를 눌러보면 웹페이즈를 구성하는 HTML 코드들이 나온다. 이를 구성하는 것이 바로 css 선택자인데, 이는 웹페이지의 각 섹션(예를 들면 로그인을 항목, 다운 받을 자료가 링크되어 있는 곳 등등 마우스로 클릭 및 여러 정보들이 있는 공간)을 의미한다.
셀레니움에서는 find_element_by_css_selector()
를 이용하여 쉽게 가능하다.
먼저 해당 사이트에서 키보드의 F12 를 눌러 소스코드 창을 열어주고, 소스코드창의 상단 왼쪽모서리에 있는 화살표 모양 버튼을 클릭하거나 단축키인 Ctrl+Shift+C를 사용하면 버튼 등의 웹페이지 요소를 마우스로 직접 선택할 수 있게 해준다.
이때 우리가 클릭해야 하는 내려받기(CSV) 버튼을 마우스를 선택하면 소스코드창에서 해당 코드 부분이 선택될 되는데, 선택된 코드가 맞는지 다시 확인하고, 코드에서 오른쪽 마우스를 클릭하여 Copy > Copy selector를 선택한다.
복사한 값은 find_element_by_css_selector()의 인자로 사용할 예정이다.
이를 코드로 구현하면 다음과 같다.
import os
wd_path = os.getenv('HOME')+'/lib/chromedriver'
#웹드라이버 실행 및 페이지 이동
# 크롬드라이버를 통해 브라우저를 띄우고
driver = webdriver.Chrome(wd_path)
# 우리가 원하는 URL로 이동.
driver.get(crawling_urls['산과공원'])
# 해당 화면이 다 로딩할 때까지 5초간 충분히 기다려 준다.
time.sleep(5)
#csv파일 다운로드 버튼 클릭하기
# 사람이 누른 것처럼 다운로드 버튼을 클릭한 후
driver.find_element_by_css_selector("#btnCsv").click()
# 다운로드가 완료될 때까지 3초간 기다려 준다.
time.sleep(3)
# 브라우저를 종료.
driver.quit()
다운받은 csv 파일을 확인¶
#다운받은 csv파일 확인
#_dir = os.getenv('HOME')+'/다운로드'
_dir = os.getenv('HOME')+'/Downloads' # 영문 우분투 사용자라면 이 경로를 선택해 주세요.
files = glob.glob('{}/서울시*.csv'.format(_dir))
print(files)
['/home/aiffel/Downloads/서울시 산과공원 생태관광 정보 (한국어).csv']
csv 파일을 DataFrame 으로 변환하기¶
#csv파일을 dataframe으로 변환하기
#인코딩 에러 발생시에 encoding옵션 추가
#CP949: windows에서 사용하는 인코딩 방식
f_M_park = pd.read_csv(files[0], encoding='CP949')
f_M_park.head(3)
키 | 명칭 | 대분류 | 주소 | 행정 시 | 행정 구 | 행정 동 | 대표전화 | 면적 | 지정일 | 교?안내 | |
---|---|---|---|---|---|---|---|---|---|---|---|
0 | BE_IW14-0020 | 진관내동 생태경관보전지역 | 생태탐방 | 은평구 진관동 282-1번지 일대(북한산국립공원 북한산성 입구 주변 습지 ) | 서울특별시 | 은평구 | 진관동 | 02-2115-7550~5 02-350-1397 | 16639㎡ | 2002년 12월 30일 | 지하철 3호선 구파발역 1번 출구에서 704번 34번 버스를 타고 북한산성 입구에서... |
1 | BE_IW14-0109 | 안산공원 | 산과공원 | 서울특별시 서대문구 홍제동 산33번지 일대 | 서울특별시 | 서대문구 | 홍제1동 | 02-330-1395 | NaN | NaN | NaN |
2 | BE_IW14-0110 | 여의도공원 | 산과공원 | 서울특별시 영등포구 여의공원로68(여의도동 2번지) | 서울특별시 | 영등포구 | 여의동 | 02-761-4079 | NaN | NaN | NaN |