본문 바로가기
공부기록/안드로이드

[JSOUP사용법] 웹(HTML) JSOUP으로 파싱하기 (웹-안드로이드 연동/네이티브앱)

by 책읽는 개발자 ami 2021. 1. 27.
728x90
반응형

서론

 스프링 프로젝트에서 게시판 작업으로 SUMMERNOTE를 사용한다. SUMMERNOTE는 글의 내용을 HTML로 저장하기 때문에 웹뷰가 아닌 네이티브 앱과 웹을 연동시키기 위해선 HTML을 파싱하는 작업이 필요했다.

SUMMERNOTE에서 이미지는 IMG태그로, 글은 P태그로 저장시키기 때문에 비교적 간단한 파싱으로 구현할 수 있었다.

프로젝트에서는 서버에서 HTML 소스를 받아오지만, 예시에선 HTML 소스를 하드코딩할 예정

결과 이미지는 맨 아래 있습니다~

환경설정

build.gradle 의 dependencies에 jsoup 라이브러리picasso 라이브러리(이미지뷰)를 추가해주세요

implementation 'org.jsoup:jsoup:1.11.3'

implementation 'com.squareup.picasso:picasso:2.71828'

코드

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity">
    <ScrollView
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
        <LinearLayout
            android:gravity="center"
            android:id="@+id/recipe_view_linearLayout"
            android:orientation="vertical"
            android:layout_width="match_parent"
            android:layout_height="wrap_content">
        </LinearLayout>
    </ScrollView>
</LinearLayout>

 

- 실제로 필요한 레이아웃은 recipe_view_linearLayout 뿐이다. (여기에 파싱해서 얻은 뷰를 자바로 넣어줄 예정)

스크롤뷰는 애교로 넣어줌


MainActivity.java

public class MainActivity extends AppCompatActivity {

    private LinearLayout recipeViewLinearLayout;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        recipeViewLinearLayout = (LinearLayout) findViewById(R.id.recipe_view_linearLayout);
        String htmlSource =
                "<p><img src=\"/app/upload/과정1.jpg\"></p>" +
                        "<p>1. 준비한 채소를 한입크기로 썹니다.</p>" +
                        "<p>2. 채소를 볶습니다.</p>" +
                        "<p>3. 토마토소스와 채소육수로 간을 합니다.</p>" +
                        "<p><img src=\"/app/upload/과정2.jpg\"></p>" +
                        "<p>기호에 따라 바질이나 허브를 추가로 넣어도 좋아요!</p>";
        Document doc = Jsoup.parse(htmlSource);
        Elements eles = doc.getAllElements();
        for (int i = 0; i < eles.size(); i++) {
            if (eles.get(i).tagName().equals("img")) {
                String src = getResources().getString(R.string.port) + eles.get(i).attr("src");
                LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
                params.bottomMargin = 30;
                ImageView iv = new ImageView(MainActivity.this);
                Picasso.get().load(src).placeholder(R.drawable.gray).into(iv);
                iv.setAdjustViewBounds(true);
                iv.setMaxHeight(800);
                iv.setLayoutParams(params);
                recipeViewLinearLayout.addView(iv);
            } else if (eles.get(i).tagName().equals("p")) {
                LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
                params.bottomMargin = 30;
                TextView tv = new TextView(MainActivity.this);
                tv.setText(eles.get(i).text());
                tv.setTextSize(TypedValue.COMPLEX_UNIT_SP, 14);
                tv.setLayoutParams(params);
                recipeViewLinearLayout.addView(tv);
            }
        }        
    }
}

 

Document doc = Jsoup.parse(htmlSource); -> html 소스 파싱

Elements eles = doc.getAllElements(); -> 모든 Element(태그)들 저장

eles 에 대해 for문으로 각각의 Element를 img태그인지 p태그인지 구분한다.

img 태그일 경우엔 attr("src")로 src 속성을 얻어와 서버주소를 더해 이미지를 가져온다.

ImageView를 생성해서 해당 uri를 Picasso 를 통해 해당 뷰에 넣어준다.

앞서 layout에서 만든 recipeViewLinearLayout에 뷰를 더해준다.

p 태그일 경우에는 text()로 내용을 가지고 온다.

TextView를 생성해서 뷰에 setText를 하고, 마찬가지로 레이아웃에 뷰를 추가한다.

 

결과

결과는 아래 사진과 같다. 왼쪽이 웹 오른쪽이 앱

웹뷰로 하면 훨씬 간단하지만, 팔로잉 등 여러 이벤트를 효과적으로 사용자에게 보이기 위해서는 네이티브 앱으로 가는게 나을 것 같다고 판단했다.

 

요상하게 모든 안드로이드 서비스 중 게시판이 제일 어려웠다. 웹이랑은 반대인듯.. 저만 그런가요.. 아니라고 해줘요ㅠ

728x90
반응형