728x90
이번에는 Jsoup을 사용해서 웹 페이지의 내용을 가져와 보겠습니다.
jsoup: 자바 HTML 파서
jsoup는 실제 HTML 및 XML 작업을 간소화하는 Java 라이브러리입니다. DOM API 메서드, CSS 및 xpath 선택기를 사용하여 URL 페칭, 데이터 구문 분석, 추출 및 조작을 위한 사용하기 쉬운 API를 제공합니다.
jsoup는 WHATWG HTML5 사양을 구현하고 최신 브라우저와 동일한 DOM으로 HTML을 파싱합니다.
URL, 파일 또는 문자열에서 HTML을 스크래핑하고 구문 분석합니다 .
DOM 트래버설이나 CSS 선택기를 사용하여 데이터를 찾아 추출합니다 .
HTML 요소 , 속성, 텍스트를 조작합니다.
XSS 공격을 방지하기 위해 안전 목록에 있는 사용자가 제출한 콘텐츠를 정리합니다 .
깔끔한 HTML을 출력합니다 .
그럼 왜 웹 스크래퍼를 만들어서 사용할까요?
- 자동화된 데이터 수집
- 반복적으로 웹페이지에서 정보를 복사해오는 번거로운 작업을 자동화합니다.
- 시간과 노력을 절약할 수 있습니다.
- 외부 데이터 활용
- 기존에 제공되지 않는 API 없이도 필요한 정보를 활용할 수 있습니다.
- 예: 특정 웹페이지의 데이터만 제공될 경우 직접 스크래핑으로 데이터 수집
- 커스터마이징 가능
- 원하는 데이터를 선택적으로 추출할 수 있어 효율적입니다.
- 특정 요소(예: 제목, 본문, 이미지 등)를 선택적으로 처리 가능
- 앱 기능 확장
- 실시간 정보를 제공하는 앱을 제작하거나, 외부 데이터를 기반으로 새로운 기능을 제공할 수 있습니다.
- 경제적 효율성
- 비용이 드는 API를 사용하지 않아도 데이터를 얻을 수 있는 방법이 됩니다
그럼 어디에 사용하면 좋을까요?
- 뉴스 앱이나 콘텐츠 수집 앱 개발
- 특정 웹사이트의 뉴스, 블로그, 또는 콘텐츠를 가져와 앱 사용자들에게 보여줄 수 있습니다.
- 예: 실시간 뉴스 피드, 블로그 통합 뷰어
- 데이터 분석 및 리서치 도구
- 특정 웹페이지에서 필요한 데이터를 수집하여 분석에 활용할 수 있습니다.
- 예: 상품 가격 비교, 키워드 트렌드 분석
- 교육 및 학습 앱
- 학습 자료나 참고 문서를 웹에서 수집해 제공하는 앱을 만들 수 있습니다.
- 예: 특정 주제의 최신 논문, 기술 자료 제공
- 이벤트 또는 정보 통합 플랫폼
- 지역 행사, 스포츠 경기 일정, 또는 기타 정보를 여러 웹사이트에서 수집해 한 곳에서 보여주는 데 사용할 수 있습니다.
- 예: 영화 상영 정보, 스포츠 경기 결과 모니터링
- 퍼스널 프로젝트
- 개인이 관심 있는 데이터를 자동으로 모으고 정리하는 데 활용할 수 있습니다.
- 예: 주식 시장 데이터 추적, 여행 정보 수집
정보를 가져옴에 따라 주의 사항이 몇가지 있습니다.
- 법적 문제
- 웹 스크래핑은 사이트 이용 약관에 따라 법적 문제가 발생할 수 있으므로 사전에 확인이 필요합니다.
- 웹사이트 구조 변경
- 웹페이지 구조가 변경되면 스크래퍼가 작동하지 않을 수 있으므로 지속적인 유지보수가 필요합니다.
- 성능
- 큰 데이터를 스크래핑하면 성능 이슈가 발생할 수 있으므로 최적화가 필요합니다.
MainActivity
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.select.Elements;
import java.io.IOException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class MainActivity extends AppCompatActivity {
TextView resultTextView;
EditText urlText;
ExecutorService executorService;
String TAG = "MainActivity";
Button urlButton;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 스크랩 해올 내용 보여주기 뷰
resultTextView = findViewById(R.id.resultTextView);
// 스크랩 할 주소
urlText = findViewById(R.id.urlEditText);
// 스크랩 찾기 버튼
urlButton = findViewById(R.id.searchButton);
// ExecutorService 초기화
executorService = Executors.newSingleThreadExecutor();
urlButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String url = urlText.getText().toString().trim();
if (!url.isEmpty()) {
scrapeWebData(url);
} else {
urlText.setText("주소를 입력하세요!");
}
}
});
}
void scrapeWebData(String url) {
executorService.execute(() -> {
try {
// Jsoup으로 HTML 문서 가져오기
Document doc = Jsoup.connect(url).get();
// 웹 페이지 제목 가져오기
String title = doc.title();
// 특정 태그(<p>) 데이터 가져오기
Elements paragraphs = doc.select("p");
StringBuilder content = new StringBuilder("Title: " + title + "\n\nContent:\n");
for (int i = 0; i < Math.min(paragraphs.size(), 5); i++) {
content.append(paragraphs.get(i).text()).append("\n");
}
// 메인 스레드에서 UI 업데이트
new Handler(Looper.getMainLooper()).post(() -> resultTextView.setText(content.toString()));
} catch (IOException e) {
e.printStackTrace();
new Handler(Looper.getMainLooper()).post(() -> resultTextView.setText("Error: " + e.getMessage()));
}
});
}
@Override
protected void onDestroy() {
super.onDestroy();
if (executorService != null && !executorService.isShutdown()) {
executorService.shutdown();
}
}
}
activity_main.xml
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="16dp">
<EditText
android:id="@+id/urlEditText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="웹사이트 URL을 입력하세요"
android:inputType="textUri"
android:padding="8dp" />
<Button
android:id="@+id/searchButton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="검색"
android:layout_marginTop="8dp" />
<TextView
android:id="@+id/resultTextView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:padding="8dp"
android:background="#EEEEEE"
android:scrollbars="vertical"
android:overScrollMode="always"
android:gravity="start"
android:text = "Loading"
android:textSize="14sp" />
</LinearLayout>
시연영상
'안드로이드 자바' 카테고리의 다른 글
[Java][Android] ClipboardManager 사용해서 복사 및 붙여넣기 구현하기 (0) | 2025.01.12 |
---|---|
[Java][Android] AnyChart 로 원형 차트 만들기 (0) | 2025.01.07 |
[Java][Android] Bundle을 활용해 액티비티 간 데이터 전달하기 (0) | 2025.01.05 |
[Java][Android] Handler를 활용한 텍스트 자동 타이핑 애니메이션 (2) | 2025.01.01 |
[Java][Android] ZoomLayout 활용하여 이미지 확대/축소하기 (0) | 2024.12.31 |