Day74

2021. 1. 27. 10:45교육과정/KOSMO

키워드 : 파이썬 스크래핑 / 

 

****

 

1. 한빛출판 로그인페이지 활용

 

(1) 

 [] 한빛출판네트워크 ( 단순 페이지 ) : 이 예문은 위키북스 출판사 교재 예문임
 <파이썬을 이용한 머신러닝, 딥러닝 실전개발 예문>
 로그인페이지 : http://www.hanbit.co.kr/member/login.html
 마이페이지 : http://www.hanbit.co.kr/myhanbit/myhanbit.html

 1. 로그인 페이지에서 개발자모드에서 로그인 form 태그를 분석
 입력태그의 name='m_id' / name='m_passwd' 확인

 2. 로그인 후에 마이페이지에서 마일리지와 한빛이코인 부분
 마일리지 (.mileage_section1 > span ) / 한빛이코인 (.mileage_section2 > span )

 3. 로그인과정에 어떤 통신이 오가는지 분석
 Network > Preserve log 체크 > Doc 탭을 선택하고 다시 처음부터 로그인을 하면 서버와 통신을 오고간다
 이 때 Name  login_proc.php를 선택하고 Headers 부분을 확인한다

 Gereral : Request Mathod : POST
 Form Data : m_id m_passwd 값 확인

 

(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) 

* Seleniumdriver객체를 통해 여러가지 메소드를 제공한다.
- HTML을 브라우저에서 파싱해주기 때문에 굳이 PythonBeautifulSoup을 사용하지 않아도 된다.

 

[ 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])

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

반응형

'교육과정 > KOSMO' 카테고리의 다른 글

Day76  (0) 2021.01.29
Day75  (0) 2021.01.28
Day73  (0) 2021.01.26
Day72  (0) 2021.01.25
Day71  (0) 2021.01.22