본문 바로가기

프로그래밍/python

파이썬으로 로그인 하기

얼마 전에 픽시브 롤러라는 프로그램을 공개했었습니다. 픽시브에서 여러장의 그림을 한번에 다운로드 할 때 유용할 프로그램이죠. 픽시브 롤러는 파이썬으로 만들어 졌었습니다. 그때 어떻게 파이썬으로 픽시브에서 그림을 다운로드 받아올 수 있었는지 알려 드리도록하겠습니다.

먼저 픽시브에서 그림을 보기 위해서는 로그인을 해야 합니다. 물론 로그인을 하지 않아도 그림을 볼 수는 있으나 원래 해상도로는 보지 못하고 해상도가 작게 조절된 그림밖에 볼 수 없습니다. 아무튼 파이썬으로 로그인 하기 위해서는 파이썬 코드로 가상으로 Login Post 요청을 날려주어야 합니다. 파이썬 2와 파이썬 3는 방법이 조금 다릅니다. 핵심이 되는 라이브러리인 urllib의 구조가 2에서 3으로 가면서 많이 바뀌었습니다. 픽시브 롤러를 만들때는 파이썬 3.2를 써서 만들었기 때문에, 파이썬 2버전 코드가 정확한지는 확신할 수 없습니다. 안되면 댓글 남겨주세요.

파이썬2와 3에서 픽시브에서 로그인 하는 방법은 다음과 같습니다. (다른 홈페이지에도 비슷하게 적용됩니다. Prarms 부분만 적절히 조정하면 됩니다.)

파이썬2

import cookielib, urllib2, urllib
cj = cookielib.CookieJar()
opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cj))
urllib2.install_opener(opener)

params = urllib.urlencode({"mode":"login", "pixiv_id":user_id, "pass":password})
req = urllib2.Request("http://www.pixiv.net/index.php", params)
res = opener.open(req)

파이썬3

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

params = urllib.parse.urlencode({"mode":"login", "pixiv_id":user_id, "pass":user_pass})
params = params.encode('utf-8')
req = urllib.request.Request("http://www.pixiv.net/index.php", params)
res = opener.open(req)

단순히 로그인만 하고 끝나면 안되고, 로그인을 하고 난 이후에 로그인정보를 가지고 사이트를 돌아다녀야 하므로 cookie를 저장해 두어야 합니다. 그래서 opener에 쿠키 저장소를 설정해 두고 로그인을 시도해야 합니다.

파이썬2

cj = cookielib.CookieJar()
opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cj))
urllib2.install_opener(opener)

파이썬3

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

이 3줄이 쿠키 저장소를 설정하는 것입니다. CookieJar()이 쿠키를 저장하는 곳이고 HTTPCookieProcessor를 이용하여 build_opener의 쿠키 저장소를 설정해 줍니다.

파이썬2

params = urllib.urlencode({"mode":"login", "pixiv_id":user_id, "pass":password})
req = urllib2.Request("http://www.pixiv.net/index.php", params)
res = opener.open(req)

파이썬3

params = urllib.parse.urlencode({"mode":"login", "pixiv_id":user_id, "pass":user_pass})
params = params.encode('utf-8')
req = urllib.request.Request("http://www.pixiv.net/index.php", params)
res = opener.open(req)

다음 실제로 로그인 하는 부분입니다. Dict 형태로 로그인 정보를 담아서 request를 보내게 됩니다. 파이썬에서 Request를 생성할 때 두번째 인자가 들어오게 되면 자동으로 Post Request로 인식하게 됩니다. 그리고 파이썬3에서는 Request의 인자를 string 형식으로 직접보낼 수 없고 'utf-8'로 인코딩을 해서 보내야 합니다.

이렇게 하면 이제 로그인을 완료 되었고 opener를 이용해서 원하는 부분을 마음껏 다닐 수 있습니다. 그런데 로그인 쿠키만 가지고 들어갈 수 없는곳이 있습니다. 큰 해상도로 된 그림을 보려고 하면 forbidden 에러가 뜹니다. 지금 브라우저에서 바로 아래 url로 접속해 보세요.

url: http://www.pixiv.net/member_illust.php?mode=big&illust_id=29525941

어떤 브라우저에서는 forbidden이라고 뜨고 어떤 브라우저에서는 http://www.pixiv.net/member_illust.php?mode=medium&illust_id=29525941(이 url을 편의상 url2로 부르겠습니다.)로 redirect될 것입니다. 로그인을 한 상태라도 말이죠. 브라우저에서 저 url로 접속하기 위해서는 그 전 페이지인 url2을 통해서 들어가야지만 들어 갈 수 있습니다. 이게 어떤식으로 이루어지는 것이냐면 url2에서 url로 접속하는 링크에는 특별한 header을 달아서 request을 보내도록 하게 되어 있습니다. 크롬의 개발콘솔로 확인해 보면 직접 접속할때와 url2를 거쳐 들어갈 때 header가 다른 것을 확인할 수 있습니다.

보이시나요? Request Headers에서 다른점을 찾지 못하신 분들을 위해 확대해서 보여드리도록하겠습니다.

 

바로 Referer 부분이 추가되어 있습니다. Header에 저 Referer를 추가해서 보내면 직접 접속이 가능해 지는 겁니다. 파이썬에서 헤더를 추가해서 접속해 보도록 하겠습니다.

파이썬2

url = "http://www.pixiv.net/member_illust.php?mode=big&illust_id=29525941"
req = urllib2.Request(url)
req.add_header("Referer", "http://www.pixiv.net/member_illust.php?mode=medium&illust_id=29525941")
res = opener.open(req)

html = read.read()
print html

파이썬3

url = "http://www.pixiv.net/member_illust.php?mode=big&illust_id=29525941"
req = urllib2.Request(url)
req.add_header("Referer", "http://www.pixiv.net/member_illust.php?mode=medium&illust_id=29525941")
res = opener.open(req)

html = read.read()
print(html)

Request 객체에 add_header로 헤더를 추가해서 보내면 올바른 html 문서를 받아오는 것을 확인 할 수 있습니다.

그리고 번외로 이미지 url을 이용해서 이미지를 다운받는 법은 다음과 같습니다.

파이썬2

url = "http://i2.pixiv.net/img28/img/geek919/29525941.jpg"
res = opener.open(url)

image = res.read()
f = open("filename.jpg", "wb")
f.write(image)
f.close()

파이썬3

url = "http://i2.pixiv.net/img28/img/geek919/29525941.jpg"
res = opener.open(url)

image = res.read()
f = open("filename.jpg", "wb")
f.write(image)
f.close()

단순히 url을 이용해서 받아온 데이터를 읽어서 바이너리 파일로 쓰면 됩니다. ("wb"는 바이너리파일을 쓸 때 사용되는 모드입니다.)

여기까지가 파이썬을 이용하여 로그인 하기 + 그 이외에 잡다한 유용한 기능들이었습니다.