Jericho로 HTML 파싱하기

안드로이드와 iOS 모두 웹뷰를 지원하므로, 앱에 웹 페이지를 끼워넣을 수 있다. 하지만, 브라우저 대비 성능이 떨어진다거나 브라우저와 동일하게 동작하지 않는 등 자잘한 이슈들이 늘 따라다니는게 웹뷰다.

어쨌든, 웹뷰를 이용해 페이지를 보여주라는 가이드를 받았지만 뷰(View)로 처리 하는 것이 더 좋다고 생각한다면 HTTP를 통해 서버와 통신하여 데이터를 가져온 후 네이티브 코드로 화면을 보여주면 된다. 여기서 일부 필요한 데이터만 처리하고 싶을 때 어떻게 해야할까? 이 때, Jericho같은 HTML 파싱 라이브러리가 필요하다. (이런 것도 있으려나 하면서 찾아봤는데, 역시 생각한 건 거의 다 있더라. 그 것도 많이.)

Jericho의 사용법은 매우 간단하다. 객체를 생성할 때 바로 URL을 건네 HTML을 바로 가져올 수도 있고, 메소드를 POST로 처리하거나 헤더에 추가적인 값을 넣어야하는 경우는 Apache HTTP Common 라이브러리를 이용해  응답을 받은 후, 응답의 바디 부분만 스트링으로 넘길 수도 있다. Jericho 홈페이지에 가면 기능과 샘플들, 다운로드 링크 등이 잘 정리되어 있다.

만약, 바디의 HTML을 파싱해서 폼 안의 이름과 값들을 모두 꺼내는 것도 아래의 몇 줄이면 충분하다.

private String getFormData() {
    StringBuilder builder = new StringBuilder();

    Source source=new Source(body);
    FormFields formFields=source.getFormFields();
    for (FormField formField : formFields) {
        if(!formField.getValues().isEmpty())
            builder.append(formField.getName() + "=" + formField.getValues().get(0) + "\n");
        else
            builder.append(formField.getName() + "=\"\"\n");
    }
    return builder.toString();
}

위와 같은 경우 폼이 아래와 같은 모양이었다면,

<!DOCTYPE html>
    <html>
    <head>
    <title></title>
    </head>
    <body>
    <form accept-charset="UTF-8" action="receipt.jsp" id="custom" method="post">
    <input id="req_bill_to_surname" name="req_bill_to_surname" type="hidden" value="Smith" />
    <input id="req_bill_to_forename" name="req_bill_to_forename" type="Joe" value="Y" />
    <input id="req_bill_to_email" name="req_bill_to_email" type="hidden" value="joesmith@example.com" />
    <input name="commit" type="Submit" value="Continue" />
</form>
</body>
</html>

결과값은 다음처럼 나온다.

...
req_bill_to_surname=Smith
req_bill_to_forename=Joe
req_bill_to_email=joesmith@example.com
...

파싱은 시간이 많이 걸리는 작업 중 하나이니, 너무 많은 데이터를 처리하는 것은 좋지 않다. 혹, 큰 페이지를 처리해야 한다면 스레드를 따로 만드는 것이 바람직하다.

그 밖에

안드로이드 액티비티와 같은 네이티브 코드 중간에 웹뷰를 통해 웹페이지가 나오는 것은 기능상 이슈 외에도 사용자에게 UX상으로도 좋지 않다. 뒤로가기 버튼이 기대하는대로 동작하지 않는 경우처럼 말이다. 그렇다고, 모든 웹뷰를 네이티브로 다시 만들려고 하지는 말자. 다 적절한 유용한 경우가 있으니까.

참조 

댓글 달기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다

이 사이트는 스팸을 줄이는 아키스밋을 사용합니다. 댓글이 어떻게 처리되는지 알아보십시오.