파이썬으로 로그인 하기

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

먼저 픽시브에서 그림을 보기 위해서는 로그인을 해야 합니다. 물론 로그인을 하지 않아도 그림을 볼 수는 있으나 원래 해상도로는 보지 못하고 해상도가 작게 조절된 그림밖에 볼 수 없습니다. 아무튼 파이썬으로 로그인 하기 위해서는 파이썬 코드로 가상으로 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"는 바이너리파일을 쓸 때 사용되는 모드입니다.)

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

신고
  • 주인장님 주소 수정/제거 답글달기 2012.11.09 14:30 신고

    올려주신 픽시브 롤러 잘 쓰고 있습니다. 그런데 유저로 다운받을 때 왠지 패키지 그림이 있는 유저는 진행이 되지 않더군요
    왜 이런지 알 수 있을까요?

    • Favicon of http://edoli.tistory.com 소리미아 에돌이 주소 수정/제거 2012.11.09 16:47 신고

      옵션중에 '첫 그림만' 이라는 옵션이 있을텐데, 이 옵션을 해제해 주시면 될겁니다. 원하시는 답이 맞는지는 정확히 모르겠네요.ㅠㅠ

  • 주인장님 주소 수정/제거 답글달기 2012.11.09 17:22 신고

    그 옵션도 해제해보거나 체크해봤는데 진행이 안되더라구요 ㅋㅋ 답해주셔서 감사합니다

  • 날스 주소 수정/제거 답글달기 2012.12.27 14:55 신고

    롤러 잘 쓰고 있습니다. 감사인사를 (__)
    예전에 한창 모으다가, 최근에 롤러를 다시 쓰려고 하는데 아티스트 ID를 입력하면 1개도 안받아지고 종료되더라고요..
    검색으로는 잘 받아지는 것 같습니다.
    이유가 뭘까요 ㅠㅠ 맘에드는 아티스트 발견했는데 장수가 너무 많아서 ㅋㅋ 노가다 엄두를 못내고 있습니다.

  • 학생 주소 수정/제거 답글달기 2013.11.07 10:42 신고

    안녕하세요 먼저 좋은 소스 감사 드립니다.

    다름이 아니라 궁금한점이 있어 댓글을 남기게 되었습니다.

    req = urllib.request.Request("http://www.pixiv.net/index.php", params)

    서버에다가 계정, 패스워드 값을 입력해서 request를 날리면 서버에서 응답 값을 보내주는데 그 응답값을 확인해보고 싶어서

    변수를 선언해서 출력을 할려고 하는데 잘 안되네요. req에 대한 응답값을 확인하기 위해서 어떤식으로 해야 하는지요..

    만약에 계정과 패스워드가 일치가 되었을 경우와 일치가 되이 않았을 경우 응답값이 궁금하여서 소스 코딩을 하고 있는데 잘 되지 않네요..;;

    참고로 파이썬 3.x 버전 입니다.

  • f 주소 수정/제거 답글달기 2014.06.04 03:20 신고

    파이썬종자 씹노답

  • 제발 주소 수정/제거 답글달기 2014.06.16 19:20 신고

    네이버에 로그인 하려면ㅇ ㅓ떻게 해야 하나요 ?? 빠른 대답 부탁드려요 ㅜ..

  • ㅜㅜ 주소 수정/제거 답글달기 2015.07.28 16:02 신고

    이거 왜 안될까요.. 로그인이 안되요...

    • ㅜㅜ 주소 수정/제거 2015.07.28 16:03 신고

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

      user_id = ''
      user_pass =

      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)


      로그인과 비밀번호를 저런식으로 처리하는게 아닌가요? 직접 넣으면 오류 나던데요

비밀 댓글