2021. 1. 27. 10:45ㆍ교육과정/KOSMO
키워드 : 파이썬 스크래핑 /
****
1. 한빛출판 로그인페이지 활용
(1)
[예] 한빛출판네트워크 ( 단순 페이지 ) : 이 예문은 위키북스 출판사 교재 예문임 |
(2) 필요한 라이브러리 임포트
import requests
from bs4 import BeautifulSoup
(3) 세션을 사용하기 위한 준비
( 실제 세션은 아니지만, 로그인이 필요한지 여부를 세션으로 파악하기 때문 )
session = requests.session()
(4) 로그인 준비
→ F12 > Network - Doc - login_proc.php - header - Form Data 확인
session = requests.session()
login_info = {
"m_id" : "실제아이디",
"m_passwd" : "실제비밀번호"
}
(5) id와 pw를 넘겨줄 페이지를 변수에 담는다.
session = requests.session()
login_info = {
"m_id" : "실제아이디",
"m_passwd" : "실제비밀번호"
}
url_login = 'https://www.hanbit.co.kr/member/login_proc.php'
(6) 세션을 사용하여 url 에 로그인 정보를 넘기고 그 결과를 출력해본다.
requests 라이브러리의 raise_for_status( ) 함수는 오류가 발생하면 예외를 발생시킨다.
url_login = 'https://www.hanbit.co.kr/member/login_proc.php'
res = session.post(url_login, login_info)
res.raise_for_status()
print(res.text)
# 실행결과 -- 정상적인 id, pw 일 경우
<script>location.href='https://www.hanbit.co.kr';</script>
# 실행결과 -- 비정상적인 id, pw 일 경우
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"><script>alert('해당 회원의 정보가 없습.....
(7) 실제 로그인을 하지 않은채로 세션값을 통해 로그인 정보를 넘긴 뒤, 마이페이지에 접근한다.
→ 로그인 했을 때의 HTML 을 가져올 수 있다.
url_mypage = 'https://www.hanbit.co.kr/myhanbit/myhanbit.html'
mypage = session.get(url_mypage)
mypage.raise_for_status()
print(mypage.text)
# 실행결과
<!DOCTYPE html>
<html lang="ko">
<head>
<!--[if lte IE 8]>
....
(8) 로그인 없이 세션 값을 전달하여, 마이페이지로부터 필요한 데이터를 추출한다.
soup = BeautifulSoup(mypage.text, 'html.parser')
mileage = soup.select_one('.mileage_section1 span')
coin = soup.select_one('.mileage_section2 span')
print('마일리지:{}점\n이코인:{}원'.format(mileage.text, coin.text))
# 실행결과
마일리지:2,000점
이코인:0원
< 전체 스크립트 >
import requests
from bs4 import BeautifulSoup
# 세션을 사용하기 위한 준비
session = requests.session()
# 로그인 준비
# F12 > Network - Doc - login_proc.php - header - Form Data 확인
login_info = {
"m_id" : "실제아이디",
"m_passwd" : "실제비밀번호"
}
# id와 pw를 넘겨줄 페이지
url_login = 'https://www.hanbit.co.kr/member/login_proc.php'
res = session.post(url_login, login_info)
res.raise_for_status() # 오류가 발생하면 예외를 발생시킴
# print(res1.text)
# 마이페이지에 접근
url_mypage = 'https://www.hanbit.co.kr/myhanbit/myhanbit.html'
mypage = session.get(url_mypage)
mypage.raise_for_status()
# print(mypage.text)
# 필요한 정보 추출
soup = BeautifulSoup(mypage.text, 'html.parser')
mileage = soup.select_one('.mileage_section1 span')
coin = soup.select_one('.mileage_section2 span')
print('마일리지:{}점\n이코인:{}원'.format(mileage.text, coin.text))
2. 셀레늄 ( selenium ) 기초
(1)
- 주로 웹앱을 테스트하는데 이용하는 프레임워크 - 웹 브라우저를 원격으로 조작할 때 사용 - 자동으로 URL을 열고 클릭, 스크롤, 문자 입력등의 동작을 조작할 수 있다. - webdriver라는 API를 통해 운영체제에 설치된 Chrome등의 브라우저를 제어하게 된다. [설치] 메뉴 > File > Settings > Project Interpreter > + 버튼 selenium 검색 후 인스톨 > pip install selenium [참고] Selenium의 버전은 자주 업데이트 되고, 브라우저의 업데이트 마다 새로운 Driver를 잡아주기 때문에 항상 최신버전을 깔아 주는 것이 좋다. [매뉴얼] ` https://selenium-python.readthedocs.io/index.html ` https://docs.seleniumhq.org/docs/ |
(2)
크롬 웹드라이버 ( Chrome WebDriver ) [다운로드] http://chromedriver.chromium.org/downloads chromedirver_win32.zip 파일 다운로드 받고 압축풀기 2019.07.24 - ChromeDriver 75.0.3770.140 ( 반드시 이 버전만 되었다 ) |
*** 셀레니움에서 지원안 할 예정 화면없는 웹 브라우저 : PhantomJS - 화면없이 명령줄을 이용 - 웹 개발시 테스트 및 성능 측정, 화면 캡쳐 등에 활용 http://phantomjs.org http://phantomjs.org/download.html 다운받아 압축푼 경로 / bin / phantomjs.exe 실행하면 콘솔 화면> console.log('hello') // 자바스크립트 명령어 |
(3)
* Selenium은 driver객체를 통해 여러가지 메소드를 제공한다.
- HTML을 브라우저에서 파싱해주기 때문에 굳이 Python와 BeautifulSoup을 사용하지 않아도 된다.
[ URL에 접근하는 api ]
get(‘http://url.com’)
(4)
1. DOM 내부에 있는 여러 요소 중 첫 번째 요소(element) 찾는다. find_element_by_name(‘HTML_name’) find_element_by_id(‘HTML_id’) find_element_by_css_selector(‘#css > div.selector’) find_element_by_class_name(‘some_class_name’) find_element_by_tag_name(‘h1’) find_element_by_xpath(‘/html/body/some/xpath’) : xpath 지정하여 해당 요소 추출 find_element_by_link_text(‘text’) : 링크 텍스트로 요소 추출 |
2. DOM에서 모든 요소 추출 find_elemens_by_css_selector(‘#css > div.selector’) find_elements_by_class_name(‘some_class_name’) find_elements_by_tag_name(‘h1’) |
3. DOM 요소에 적용할 수 있는 메소드와 속성 clear() : 글자를 지움 click() : 클릭 get_attribute(name) : 요소의 속성 name에 해당하는 값을 추출 is_displayed() : 요소가 화면에 출력되는지 확인 is_enabled() is_selected() save_screenshot(filename) submit() |
그 외 등등...
3. 셀레늄 ( selenium ) - (1) 다음사이트에서 사용해보기
(1) 파이참에서 셀레늄 다운로드
→ [설치] 메뉴 > File > Settings > Project Interpreter > + 버튼
selenium 검색 후 인스톨
(2) 크롬 웹 드라이버 다운로드
① 크롬 버전 확인
② http://chromedriver.chromium.org/downloads 접속 후 크롬 버전에 맞는 링크 클릭
③ chromedirver_win32.zip 다운로드 후 파이썬 작업 파일이 있는 경로에 압축 해제
(3) 셀레늄 라이브러리로부터 웹드라이버 모듈을 임포트
from selenium import webdriver
(4) 웹드라이버 객체를 생성
# 셀레늄은 기본적으로 웹 자원들이 로드될 때까지 대기하지만, # 압묵적으로 기다리기 위해 2초 여유를 지정 |
from selenium import webdriver
driver = webdriver.Chrome('./webdriver/chromedriver.exe')
driver.implicitly_wait(2)
(5) 드라이버를 사용하여 웹 페이지 접근 후 화면 캡처 및 저장을 한다.
driver.get('https://daum.net')
driver.save_screenshot('daum_main.png')
< 전체 스크립트 >
from selenium import webdriver
# 1. webdriver 객체생성
driver = webdriver.Chrome('./webdriver/chromedriver.exe')
driver.implicitly_wait(2)
# 셀레늄은 기본적으로 웹 자원들이 로드될 때까지 대기하지만,
# 압묵적으로 기다리기 위해 2초 여유를 지정
# 2. 페이지 접근
driver.get('https://daum.net')
# 3. 화면을 캡처해서 저장하기
driver.save_screenshot('daum_main.png')
4. 셀레늄 ( selenium ) - (2) 구글사이트에서 사용해보기
(1) 필요한 모듈 임포트
from selenium import webdriver
(2) 웹드라이버 객체를 생성
from selenium import webdriver
driver = webdriver.Chrome('./webdriver/chromedriver.exe')
driver.implicitly_wait(2)
(3) 웹드라이버로 구글 페이지에 접근
driver.get('https://google.com')
(4) 구글에서 '플레이데이터' 라고 검색 후 개발자모드에서 검색창의 name, value 와 검색버튼의 type 확인
(4) form 태그의 요소 중 name 을 찾아 변수 q 로 지정한 뒤, 검색할 키워드를 send_keys( ) 로 넘긴다.
driver.get('https://google.com')
q = driver.find_element_by_name('q')
q.send_keys('코로나 극복')
q.submit()
(5) 실행결과 - 크롤링의 시작점으로 활용할 수 있다.
< 전체 스크립트 >
from selenium import webdriver
# [1] 객체 생성
driver = webdriver.Chrome('./webdriver/chromedriver.exe')
driver.implicitly_wait(2)
#----------------------------------------------
# [2] 페이지 접근
driver.get('https://google.com')
# [3] form 태그에서 name 찾아 검색 키워드를 send_keys 로 입력
q = driver.find_element_by_name('q')
q.send_keys('코로나 극복')
q.submit()
5. 셀레늄 ( selenium ) - (3) 네이버 로그인하기
(1) 필요한 모듈 임포트 후 로그인 정보 작성
from selenium import webdriver
myID = '실제아이디'
myPW = '실제비밀번호'
(2) 웹 드라이버 객체 생성
driver = webdriver.Chrome('./webdriver/chromedriver')
driver.implicitly_wait(3)
(3) 페이지 접근 후 입력창에 값 넣기
driver.get('https://nid.naver.com/nidlogin.login')
driver.find_element_by_name('id').send_keys(myID)
driver.find_element_by_name('pw').send_keys(myPW)
(4) 로그인 버튼 클릭
login = driver.find_element_by_id('log.login')
login.click()
(5) 실행결과 --- 자동화 방지 보안으로 인해 실패한다.
(6) 우회해서 로그인
from selenium import webdriver
myID = '실제아이디'
myPW = '실제비밀번호'
driver = webdriver.Chrome('./webdriver/chromedriver')
driver.implicitly_wait(3)
driver.get('https://nid.naver.com/nidlogin.login')
driver.execute_script("document.getElementsByname('id')[0].value=\'"+myID+"\'")
driver.execute_script("document.getElementsByname('pw')[0].value=\'"+myPW+"\'")
driver.find_element_by_xpath('//*[@id="frmNIDLogin"]/fieldset/input').click()
driver.find_element_by_id('log.login').click()
6. 셀레늄 ( selenium ) - (4) 페이스북 로그인하기
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
myID = '실제이메일'
myPW = '실제비밀번호'
driver = webdriver.Chrome('./webdriver/chromedriver.exe')
driver.implicitly_wait(3)
driver.get('https://www.facebook.com/')
driver.find_element_by_id('email').send_keys(myID)
driver.find_element_by_id('pass').send_keys(myPW)
driver.find_element_by_name('login').click()
6. 셀레늄 ( selenium ) - (4) 넥슨 홈페이지 로그인하기
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
myID = '실제아이디'
myPW = '실제비밀번호'
driver = webdriver.Chrome('./webdriver/chromedriver.exe')
driver.implicitly_wait(3)
driver.get('http://mabinogi.nexon.com/page/main/index.asp')
driver.execute_script('go_home()')
driver.implicitly_wait(3)
driver.find_element_by_id('nid').send_keys(myID)
driver.find_element_by_id('npw').send_keys(myPW)
driver.execute_script('NexonLogin()')
8. 셀레늄 ( selenium ) - (5) 굽네치킨에서 각 페이지의 정보 스크래핑하기
(1) 필요한 모듈 임포트 및 객체생성, 페이지 접근하기
from selenium import webdriver
driver = webdriver.Chrome('./webdriver/chromedriver')
driver.implicitly_wait(3)
driver.get('http://www.goobne.co.kr/store/search_store.jsp')
(2) 페이지를 가져오는지 확인
driver.get('http://www.goobne.co.kr/store/search_store.jsp')
html = driver.page_source
print(html)
# 실행결과
<html lang="ko"><head>
<!-- Header doc -->
<title>굽네치킨</title>
....
(3) 2페이지의 정보로 바꿔서 가져오기
driver.get('http://www.goobne.co.kr/store/search_store.jsp')
driver.execute_script('store.getList("2")')
time.sleep(3)
html = driver.page_source
(4) 가져온 페이지의 정보를 HTML을 파싱
soup = BeautifulSoup(html, 'html.parser')
(5) // 화성남양점 (031-651-9294) : 주소 //의 형태로 출력하기
for store in soup.select('tbody#store_list'):
shopname = store.select('td:nth-child(1)')
tel = store.select('td:nth-child(2) > a')
addr = store.select('td:nth-child(3) > a')
for sname, tel, addr in zip(shopname, tel, addr):
print('{} ({}) : {}'.format(sname.text, tel.text, addr.text))
# 실행결과
화성남양점 (031-356-9207) : 경기도 화성시 남양동 남양도시개발구역 2-1블럭 화성남양상가 103
화서1동점 (031-248-6999) : 경기도 수원시 팔달구 화서동 219-1번지 101호
....
< 여기까지 전체 스크립트 >
from selenium import webdriver
import time
from bs4 import BeautifulSoup
#-------------------------------1. 웹 페이지 접근
# 웹드라이버 객체 생성
driver = webdriver.Chrome('./webdriver/chromedriver')
driver.implicitly_wait(3)
# 페이지 접근
driver.get('http://www.goobne.co.kr/store/search_store.jsp')
# 페이지를 잘 가져오는지 확인
# html = driver.page_source
# print(html)
# 2페이지의 정보 가져오기
driver.execute_script('store.getList("2")')
time.sleep(3)
html = driver.page_source
# print(html)
#-------------------------------2. 특정 요소 가져오기
soup = BeautifulSoup(html, 'html.parser')
# imsi = soup.findAll('tbody', attrs={"id":"store_list"})
for store in soup.select('tbody#store_list'):
# print(store)
shopname = store.select('td:nth-child(1)')
tel = store.select('td:nth-child(2) > a')
addr = store.select('td:nth-child(3) > a')
for sname, tel, addr in zip(shopname, tel, addr):
print('{} ({}) : {}'.format(sname.text, tel.text, addr.text))
(6) 1~10페이지까지 모든 매장 정보 가져오기
→ 페이지 숫자 대신 반복문을 사용한다.
for idx in range (1, 11):
driver.execute_script('store.getList("%d")')
time.sleep(3)
html = driver.page_source
....
< 여기까지 전체 스크립트 >
from selenium import webdriver
import time
from bs4 import BeautifulSoup
driver = webdriver.Chrome('./webdriver/chromedriver')
driver.implicitly_wait(3)
driver.get('http://www.goobne.co.kr/store/search_store.jsp')
for idx in range (1, 11):
driver.execute_script('store.getList("%d")')
time.sleep(3)
html = driver.page_source
soup = BeautifulSoup(html, 'html.parser')
for store in soup.select('tbody#store_list'):
shopname = store.select('td:nth-child(1)')
tel = store.select('td:nth-child(2) > a')
addr = store.select('td:nth-child(3) > a')
for sname, tel, addr in zip(shopname, tel, addr):
print('{} ({}) : {}'.format(sname.text, tel.text, addr.text))
(7) 가져온 정보를 데이터로 활용하려면 리스트에 담아야 한다.
goobne_result = []
for idx in range (1, 11):
....
for store in soup.select('tbody#store_list'):
....
for n, t, a in zip(shopname, tel, addr):
goobne_result.append([n.text, t.text, a.text])
print('전체매장수 :', len(goobne_result))
print('첫번째 출력매장 :', goobne_result[0][0])