웹크롤링 - 로그인이 필요한 웹페이지 크롤링 이해 및 실습

7. 로그인이 필요한 웹페이지 크롤링 이해 및 실습

  • 로그인이 필요한 웹페이지는 쿠키 또는 세션을 사용하는 경우가 일반적입니다.

7.1 한빛미디어 홈페이지(http://www.hanbit.co.kr) 마일리지 크롤링

  • 마일리지를 확인하기 위해 로그인 정보가 필요함
  • 세션으로 관리되고 있음을 코드를 통해 확인
  • 세션 정보를 획득하고, 이를 사용해서 마일리지 페이지에 접근하여 마일리지 점수 확인

7.1.1 로그인 페이지 분석

  • http://www.hanbit.co.kr/member/login.html
  • form 태그를 이해할 필요가 있음 (http://pythonscraping.com/pages/files/form.html)
  • form 태그를 통해 ID/PW가 전달되는 것이 일반적이므로 해당 코드 확인 (웹브라우저에서 해당 웹페이지 소스보기로 확인)
  • 다음 두 태그가 코드를 이해하는데 핵심
    <form name="frm"  id="frm"  action="#" method="post">
    <input  type="button" name="login_btn"  id="login_btn" value="로그인" class="btn_login" >
  • javascript를 간결하게 만들기 위한 라이브러리인 jQuery 코드를 확인할 필요가 있음
$(document).ready(function() { 
    $('#login_btn').click(function(){ login_proc(); });										
});


function login_proc(){					
    var chk_rule =  "m_id:isEmpty:아이디를 입력"				
                        +"@m_passwd:isEmpty:비밀번호를 입력"																																			
                        ;											 
    if(validateForm(chk_rule)){	
        $("#frm").attr("action","login_proc.php");
        $("#frm").submit();		
        //console.log("validate success!!");
    }
}
  • id가 login_btn 인 태그(input type="button")가 click 되었을 때 login_proc() 함수를 호출하게 되어 있음
$('#login_btn').click(function(){ login_proc(); });	
  • id가 frm 인 태그(form 태그)에 action 속성을 login_proc.php 로 바꿔주고, 전송하게 되어 있음
$("#frm").attr("action","login_proc.php");
$("#frm").submit();
  • 유추하는데 도움이 되는 툴
    • Chrome 개발자 도구 -> Network -> Check 'Preserver log' and Select 'Doc'
      1. Go www.hanbit.co.kr/index.html
      2. Add ID/PW and click 로그인
    • login.html -> login_proc.php -> index.html 로 호출됨을 확인할 수 있음
    • login_proc.php Request Method가 POST 이고, FORM 데이터에서 m_id, m_passwd 를 확인할 수 있음
import requests
from bs4 import BeautifulSoup

login_url = 'http://www.hanbit.co.kr/member/login_proc.php'

user = ''
password = ''

# requests.session 메서드는 해당 reqeusts를 사용하는 동안 cookie를 header에 유지하도록 하여
# 세션이 필요한 HTTP 요청에 사용됩니다.
session = requests.session()

params = dict()
params['m_id'] = user
params['m_passwd'] = password

# javascrit(jQuery) 코드를 분석해보니, 결국 login_proc.php 를 m_id 와 m_passwd 값과 함께
# POST로 호출하기 때문에 다음과 같이 requests.session.post() 메서드를 활용하였습니다.
# 실제코드: <form name="frm"  id="frm"  action="#" method="post">
res = session.post(login_url, data = params) 

# 응답코드가 200 즉, OK가 아닌 경우 에러를 발생시키는 메서드입니다.
res.raise_for_status() 

# 'Set-Cookie'로 PHPSESSID 라는 세션 ID 값이 넘어옴을 알 수 있다.
# print(res.headers)

# cookie로 세션을 로그인 상태를 관리하는 상태를 확인해보기 위한 코드입니다.
# print(session.cookies.get_dict()) 

# 여기서부터는 로그인이 된 세션이 유지됩니다. session 에 header에는 Cookie에 PHPSESSID가 들어갑니다.
mypage_url = 'http://www.hanbit.co.kr/myhanbit/myhanbit.html'
res = session.get(mypage_url)

# 응답코드가 200 즉, OK가 아닌 경우 에러를 발생시키는 메서드입니다.
res.raise_for_status() 

soup = BeautifulSoup(res.text, 'html.parser')

# Chrome 개발자 도구에서 CSS SELECTOR를 통해 간단히 가져온 CSS SELECTOR 표현식을 사용
he_coin = soup.select_one('#container > div > div.sm_mymileage > dl.mileage_section2 > dd > span')

# 다음과 같이 class를 .mileage_section2 로 그리고 그 하부 태그중에 span이 있다는 식으로 표현도 가능함
# he_coin = soup.select_one('.mileage_section2 span')

print ('mileage is', he_coin.get_text())
mileage is 5,650
연습문제1
1. 한빛미디어 마이한빛에서 회원등급 가져와서 출력하기 (기본)
2. 한빛미디어 이름, 회원등급, 마일리지 가져와서 출력하기 (중급)