아래 포스팅한 JSoup 이용하여 웹툰 다운로드하기 의 마지막에서도 언급하였듯이 웹툰 다운로드를 할 때 로그인이 필요한 부분이 있다.
19세 이상 웹툰인경우는 네이버 아이디로 로그인을 해야만 볼 수 있다.
HtmlUnit을 이용하여 처리를 하였다.
방법은 아래와 같다.
NaverLogin.java package com.web.get.comic.service; import java.io.IOException; import java.util.HashMap; import java.util.Map; import com.gargoylesoftware.htmlunit.BrowserVersion; import com.gargoylesoftware.htmlunit.CookieManager; import com.gargoylesoftware.htmlunit.WebClient; import com.gargoylesoftware.htmlunit.html.HtmlForm; import com.gargoylesoftware.htmlunit.html.HtmlImageInput; import com.gargoylesoftware.htmlunit.html.HtmlPage; import com.gargoylesoftware.htmlunit.html.HtmlPasswordInput; import com.gargoylesoftware.htmlunit.html.HtmlTextInput; import com.gargoylesoftware.htmlunit.util.Cookie; public class NaverLogin implements ILogin { public static Map간단하게 설명을 하자면 아래와 같다cookies; private static final String URL_LOGIN = "http://static.nid.naver.com/login.nhn"; private boolean isLogin; private WebClient webClient; private HtmlPage currPage; @Override public Map getCookies() { return makeLoginCookie(); } @Override public boolean isLogin() { return isLogin; } public NaverLogin(String id, String pw) throws Exception { webClient = new WebClient(BrowserVersion.FIREFOX_38); webClient.waitForBackgroundJavaScript(5000); if(!login(id, pw)) { isLogin = false; throw new Exception("cannot login with the id and pw"); } else { isLogin = true; } } private Map makeLoginCookie() { cookies = new HashMap (); CookieManager cookieManager = webClient.getCookieManager(); java.util.Set cookieSet = cookieManager.getCookies(); for(Cookie c : cookieSet) { cookies.put(c.getName(), c.getValue()); } return cookies; } private boolean login(String naverId, String naverPw) throws Exception { currPage = webClient.getPage(URL_LOGIN); HtmlForm form = currPage.getFormByName("frmNIDLogin"); HtmlTextInput inputId = form.getInputByName("id"); HtmlPasswordInput inputPw = (HtmlPasswordInput)form.getInputByName("pw"); HtmlImageInput button = (HtmlImageInput)form .getByXPath("//input[@alt='로그인']").get(0); inputId.setValueAttribute(naverId); inputPw.setValueAttribute(naverPw); currPage = (HtmlPage)button.click(); return !currPage.asText().contains("Naver Sign in"); } }
url의 내용을 webClient 객체로 가져온다음 가져온 내용에서 form을 찾는다.
form을 찾아서 id와 pw 값을 셋팅 후 로그인 버튼을 클릭해준다.(물론 실제로 개발자가 클릭하는것이 아니고 로그인 버튼을 찾아서 client event를 넘겨주는것이다.)
로그인 버튼 클릭 완료 후 넘겨받은 page 의 값을 확인하여 로그인 여부를 처리한다.
만약, 로그인 처리가 되었다면 cookie를 저장한다.
ComicImageDownMain은 아래와 같이 NaverLogin.java를 호출해서 사용하면 된다.
private ILogin loginService; public Document getDocument(String url) throws IOException { if(loginService == null) { try { loginService = new NaverLogin("아이디", "비밀번호"); if(loginService.isLogin()) { loginCookies = loginService.getCookies(); // 로그인되었으면 cookies를 가져온다. } } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } Document doc = null; if(loginCookies != null) doc = Jsoup.connect(url).cookies(loginCookies).get(); else doc = Jsoup.connect(url).get(); return doc; }
getDocument()에서 loginService를 호출한다.
로그인이 제대로 되었다면 cookies를 가져온다.
if(loginCookies != null) doc = Jsoup.connect(url).cookies(loginCookies).get(); // 쿠키가 null이 아니면 jsoup을 이용해 url의 내용을 가져온다.
이후 단계는 JSoup 이용하여 웹툰 다운로드하기 에서 설명한 부분과 동일하다.
ps. project에서 site의 data를 migration 해야할 일이 있었는데 망이 분리 되어있어서 db로 처리하기 까다롭고 또 새로 설계한 테이블에 맞도록 쿼리를 작성하는데 시간이 걸릴뻔 했는데
이미 project를 하면서 business logic을 작성해 놓았기 때문에 기존 사이트의 정보를 htmlunit으로 가지고 와서 business logic을 태웠더니 아주 훌륭하게 migration이 되었다.
위말인즉슨 business logic 처리 테스트도 같이 된다는 의미로 1석 2조의 효과를 볼 수 있었다.
htmlunit을 이용한 이유는 사이트의 첨부파일을 다운로드 받아야 했기 때문이다.
그리고 기존 사이트에서 막아놓았는지 게시물 목록에서 get 방식을 이용해서는 view 화면으로 들어갈 수 없었다.
그래서 htmlunit을 이용해서 동적 form을 생성한 후 parameter를 설정 한다음 submit 처리해주니 view 화면으로 들어갈 수 있었고
첨부파일도 다운로드가 잘 되었다.
'컴퓨터관련' 카테고리의 다른 글
Oracle 주민번호 형식 컬럼 조회 및 일괄 업데이트 (0) | 2016.08.03 |
---|---|
Mysql Function 한글 깨졌을때 (0) | 2016.08.02 |
JSoup 이용하여 웹툰 다운로드하기 (0) | 2016.03.23 |
Spring properties 사용 (0) | 2016.03.22 |
Spring xml 파일을 읽어들여 JSoup으로 Parsing하기 (0) | 2016.03.22 |