본문으로 바로가기
728x90
반응형
본 포스팅은 이전 블로그로부터 백업된 글입니다.
이전 작성일: 2018-11-08


개요

저는 주로 어떤 사이트에 로그인을 실행하는 기능을 만들 때 Selenium과 Chrome Driver 이 두 개를 활용해 특정 Login Form이나 Html Tag를 찾아 selenium 모듈의 webdriver 객체의 "find_element_by_name" 과 같은 메서드를 이용합니다 헌데 이번에 쓰는 Urllib의 기능은 이런 순서와는 좀 다르게 쿠키값을 수정해 보내는 형식으로 로그인을 해보겠습니다. 'GET' 방식이나 'POST' 방식으로 로그인 하는 것도 가능하다고 합니다 이 글에서 쓰는 방식은 정확하게 말하면 보내는 쿠키 값을 수정하는 것이지만 POST 방식의 헤더를 수정하는 것이기 때문에 POST 방식도 될 수 있다고 생각합니다.

이용할 사이트는 https://mail.mokpo.ac.kr 이고 목포대학교의 웹 메일 URL 입니다. 저는 이 대학의 학생이기 때문에 ID 랑 Password 를 쓸 수 있지만 혹시나 이 글에 나온 코드를 그대로 따라 해보려고 하시는 분들은 제한적인 요소가 있으실 거라 생각되기 때문에 어디까지나 이러한 기능이 있구나 정도의 글로 봐주시면 감사합니다.

 

urllib.request & parse

import urllib.request
import urllib.parse

urllib를 쓰기 위한 기본적인 뼈대라 생각하시면 됩니다 urllib.request는 request를 urllib.parse는 urlencode을 수행하는 기능을 해줍니다.


http.cookiejar Module

import http.cookiejar

cj = http.cookiejar.LWPCookieJar()
opener = urllib.request.build_opener(urllib.request.HTTPCookieProcessor(cj))

mail.mokpo.ac.kr 은 쿠키를 이용하기 때문에 클라이언트가 쿠키정보를 가지고 있어야 합니다 LWPCookieJar()라는 것은 사용할 쿠키를 초기화(?) 하는 것이고 HTTPCookieProcessor() 를 이용해 이 쿠키를 설정해줍니다 ( 아마도 사용할 쿠키를 실체화 시키는 로직 같습니다 ) 그렇게 초기화 시킨 쿠키를 build_opener를 통해 저장해두는 코드입니다


Setup

BaseURL = "http://mail.mokpo.ac.kr/"
url = "http://mail.mokpo.ac.kr/login_pool.jsp"

MailBoxURL = "http://mail.mokpo.ac.kr/leftmenu.jsp?color=red&gw_sms=null&gw_mail=true"

params = urllib.parse.urlencode(values)
params = params.encode("utf8")

req1 = urllib.request.Request(url,params)
res1 = opener.open(req1)

BaseURL은 처음에 접근할 URL을 의미합니다 여기서는 먼저 Login Page에 접속해야 하기 때문에 기본 Page의 URL 주소를 잡았습니다그 밑의 "url"  변수를 "http://mail.mokpo.ac.kr/login_pool.jsp"라는 주소를 초기화했습니다 실제 이 주소는 접근할 수 없는 주소 입니다 하지만 Login ID 와 Password를 보내서 실제로 로그인을 동작시키는 주소기 때문에 mail.mokpo.ac.kr에 로그인 하기 위해선 중요한 URL입니다. MailBoxURL은 "받은 편지함","보낸 편지함" 과 같은 기능을 이용할 수 있게 클라이언트가 서버에서 받아오는 하나의 Html Frame 과 같습니다

위의 사진은 burp suite를 사용해 Login 요청을 보내는 헤더를 잡은 내용입니다 보시면 POST 방식으로 login_pool.jsp에 무엇인가 보낸다는 라는 느낌을 받을 수 있습니다 그 내용은 밑에서 3번째 줄에 Cookie를 보시면 JESSIONID 와 그 밑의 LoginID 그리고 &x ,&y ,&password ,p_lang 등등 여러가지가 보이는 걸 알 수 있습니다 눈치가 빠르신 분들은 이미 아시겠지만 이 부분을 수정해서 보내게 되면 Login을 할 수 있게 되는 겁니다. "쿠키" 값을 어떻게 바꾸냐 하면 이미 언급했던 urllib.parse.encode(valuse) 를 이용하면 됩니다 values에 있는 내용은 Python에서는 Dict 형으로 설정해줘야 하고 그 내용은 다음과 같이 작성했습니다.

values = {
    "LoginID":ID,
    "x":"0",
    "y":"0",
    "password":password,
    "p_lang":""
}

 

values 와 같은 형식으로 urlencode()를 수행하셨다면 그 밑에 줄에 encode("utf8')를 통해 bytes type으로 Casting(형변환)을 해줘야합니다
req1 = urllib.request.Request(url,params)
req1은 그렇게 수정한 쿠키 값을 params 라는 2번째 파라미터로 전달하고
res1 = opener.open(req1)

res1 은 그 요청을 수행한 url 주소를 open합니다 (정확한 의미는 찾을 수 없었으나 제가 써 본 결과 open의 의미는 url이 포함하고 있는 Html 의 정보를 받아온다는 뜻으로 보입니다)

예외 처리 

try:
    GetMailBox = urllib.request.Request(MailBoxURL,params)
    respone = opener.open(GetMailBox)
    content = respone.read()
    MailParsing+=content.decode("utf8")

except Exception as e:
    print(e)

위에서 보이는 코드는 MailBoxURL에 보이는 주소의 값을 요청한 뒤 요청된 값을 저장한 뒤 "받은 편지함","보낸 편지함" 과 같은 정보를 담고 있는 Html Tag를 찾기 위해서 쓰는 코드입니다

굳이 예외 처리가 필요한가 싶은 정도의 코드이지만 burp suite로 보게 되면 MailBoxURL의 URL은 매번 Request를 할 때 마다 Request가 되는 Url Page가 다르기 때문에 MailBoxURL이 아닌 경우에는 ( 순서가 MailBoxURL 이 아닌 경우 ) Error를 내뿜으면서 종료가 됩니다. 예외처리는 이 MailBoxURL 맞을 때까지 찾고 나머지 URL 주소에 대해서는 pass를 시킵니다. 


URL Filter 

UrlFilter1 = []
UrlFilter2 = []
UrlFilter3 = []

MailLIst = []

UrlFilter1 += MailParsing.split(';')

for rd in UrlFilter1:
    if "\r\n" in  rd:
        UrlFilter2.append(rd.replace("\r\n",''))
del UrlFilter1

for rd in UrlFilter2:
    if "\t" in rd:
        UrlFilter3.append(rd.replace('\t',''))
    else:
        UrlFilter3.append(rd)
del UrlFilter2

for rd in UrlFilter3:
    SaveMailIndex = rd.find("list.jsp?")
    SaveMailIndex2 = rd.find("')")
    if SaveMailIndex != -1:
        ClearUrl = rd[SaveMailIndex::].replace("')",'')
       # print(ClearUrl)
        MailLIst.append(ClearUrl)

이 부분은 자세하게 설명하면 길어지니 간단히 설명 드리자면 앞에서 받아왔던 MailBoxURL의 메일함을 Html Tag를 찾아 그 URL를 Parsing 해주는 코드입니다. MailLIst 변수는 그 Parsing 된 URL 주소만 뽑아서 담아주는 리스트 입니다



받은 편지함에 있는 내용의  HTML TAG 찾기

GetMailBox = urllib.request.Request(BaseURL+MailLIst[0], params)
res2 = opener.open(GetMailBox)

soup = BeautifulSoup(res2,"html.parser")
Table_Find = soup.find("td",{"width":"100%"})
Table_Find2 = Table_Find.find("table",{"class":"dataTable"})

MailList[0]는 "받은 편지함"에 있는 Url이 파싱된 문자열 타입의 data 입니다 이 부분을 거의 BaseURL에 연결해 접근하게 되면 받은 편지함에 접근 할 수 있습니다. res2는 그렇게 요청한 GetMailBox를 open 하고 BeautifulSoup를 이용해 html 구조를 관찰한 다음 Table_FInd  Table_Find2를 통해 받은 메일 목록을 가져옵니다 BeautifulSoup를 쓰실 때 따로 from bs4 import BeautifulSoup4로 import를 하셔야 사용이 가능합니다 설치가 안 되어 있으시면 pip install beatifulsoup4 로 설치하시면 됩니다.

 

나머지 

DataString = ""

for rd in Table_Find2.findAll("td"):
    DataString += rd.text
DataString = DataString.strip()

ScrapingSplitList,ScrapingSplitList2,ScrapingSplitList3 = [],[],[]

print("====  Scraping ! ====")

for rd in DataString:
   if ' ' == rd:
        ScrapingSplitList.append(' ')
   if ' ' != rd:
        ScrapingSplitList.append(rd)
tmpstr = str()

for rd in ScrapingSplitList:
    if rd != '\xa0':
        tmp = []
        tmpstr += rd
        tmp.append(tmpstr)

    elif rd == '\xa0':
        ScrapingSplitList2.append(tmp)
        tmpstr = str()


for rd,count in zip(ScrapingSplitList2,range(len(ScrapingSplitList2))):
    tmp = []

    try:
        if ScrapingSplitList2[count] == ScrapingSplitList2[count+1]:
            ScrapingSplitList3.append(ScrapingSplitList2[count])
        if count+1 == max(range(len(ScrapingSplitList2))):
            ScrapingSplitList3.append(ScrapingSplitList2[count])
            ScrapingSplitList3.append(ScrapingSplitList2[count+1])
    except:
        pass

DataString 변수는 Table_Find2 에서 찾은 받은 편지함의 텍스트 정보를 저장합니다 그 밑의 ScrapingSplitLIst 변수들은 텍스트 정보를 나눠서 각각 필터링 시켜주는 용도로 사용되었습니다

이런 과정을 거치면 위의 사진과 같이 결과가 나옵니다. 메일의 내용은 개인적인 정보라 가렸습니다

기타

urllib를 통해서 웹 메일 로그인을 시도해봤습니다. 비교적 밑에 있는 설명은 되게 짧은데 이 부분은 텍스트 정보를 어떻게 자르고, 나누고, 붙일까 라는 개념이기 때문에 urllib를 쓰는 것과는 다르기 때문에 짧게 적었습니다. 만들 떄는 어려웠지만 만들고 나서 보니 비교적 쉬운 코드네요 . 앞서 언급했듯이 예제를 따라하시는 게 제한적인 요소가 있을 겁니다. 저는 대학에 학적이 있는 상태라 이 학교 메일을 쓸 수가 있지만 다른 분들은 그렇지 않으신 분도 있을테니 이 글을 보시는 분들은 '이 사람은 urllib를 이렇게 사용했구나' 정도의 글로써 참고해주시면 감사합니다.

 

참고 URL

    urllib 에서 cookie 를 생성하는 법:

    BLOG NAME 에돌이의 얕고 넓은 샘 : http://edoli.tistory.com/46

 

728x90
반응형