[java] jsoup 활용해서 이베이 크롤링하기

728x90
반응형

 

크롤링이 해보고 싶어졌다.

파이썬으로 크롤링을 많이 하는 거 같았는데 나는 자바로 진행했다. 

왜냐면 파이썬은 모르니까 ㅎㅎ!

 

참고

윈들리라는 프로그램을 벤치마킹 했다.

https://windly.cc/#feature

 

윈들리 - 이미지번역까지 가능한 올인원 구매대행 솔루션

상세이미지 AI번역 이제는 중국어 가득한 이미지 그대로 올리지 마세요. 포토샵 없이 윈들리 하나로 깔끔한 한국어 페이지를 만들고, 매출을 2배 이상 높이세요.

windly.cc

출처 - 윈들리 홈페이지(https://windly.cc/#feature)

url상품 정보를 가져오는 것이다. 

이 프로그램은 정말 많은 정보를 가져오고 깔끔한 ui를 구현해놨다. 

기본정보, 이미지, 옵션, 판매가, 상품 속성, 상세페이지가 탭으로 나뉘어져있고

각 탭마다 기능들이 세분화 되어있다. 

우리는 간단하게 상품명, 옵션, 가격, 상세페이지, 이미지 만 가져오기로 했다. 

 

 

개발환경

springboot

java8

mysql

 

Seleninum과 jsoup 차이

크롤링을 검색해보니 Selenium과 jsoup 라이브러리를 많이 사용하던데

jsoup은 보통 정적인 자료를 크롤링할때 사용하고

Selenium동적인 자료빅데이터관련 자료에 사용한다고 한다. 

 

내가 크롤링하려는건 동적인것도 아니고 빅데이터도 아니기에 jsoup으로 결정했다.

그리고 무엇보다 Selenium보다 jsoup이 속도가 빠르다고 한다.

 

 

크롤링 대상

크롤링 대상은 바로 이베이 상세페이지다.

사실 이베이는 이미 옥션에서 지원해주고 있긴하지만 처음에 아마존으로 시도했더니

차단을 하는건지 됐다 안됐다 해서 사이트를 뚫는게 목적이 아니라 크롤링으로 상품 정보를 가져오는것이 목적이므로

이베이로 정했다.

https://www.ebay.com/itm/383791923777?_trkparms=pageci%3A4339b846-5362-11ed-b6af-1e168d1a5c85%7Cparentrq%3A089b3aec1840ab9e877494c8fffd3e0a%7Ciid%3A1 

 

2020 애플 아이패드 8세대 32/128GB 와이파이 10.2인치 최신 모델 | eBay

Find many great new & used options and get the best deals for 2020 애플 아이패드 8세대 32/128GB 와이파이 10.2인치 최신 모델 at the best online prices at eBay! Free shipping for many products!

www.ebay.com

 

코드

https://jsoup.org/download

 

Download and install jsoup

Download and install jsoup jsoup is available as a downloadable .jar java library. The current release version is 1.15.3. What's new See the 1.15.3 release announcement for the latest changes, or the changelog for the full history. Previous releases of jso

jsoup.org

필요한 라이브러리인 jsoup을 다운받는다.

implementation 'org.jsoup:jsoup:1.15.3'

나는 그래들을 사용했기 때문에 해당 코드를 넣어줬다.

 

 

package com.miniProject.component;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.jsoup.Connection;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import com.miniProject.common.util.StringUtil;

public class JsoupComponent {
	
	private static final String EBAY_PRODUCT_INFO_CARD_CLASS 	= "#CenterPanelInternal";		//상품 정보 카드
	private static final String EBAY_PRODUCT_DETAIL_CARD_CLASS 	= "#vi-desc-maincntr";			//상품 상세 카드
	
	private static final String EBAY_PRODUCT_TITLE_CLASS 		= ".x-item-title__mainTitle";	//상품 제목
	private static final String EBAY_PRODUCT_PRICE_SELECTOR 	= "#prcIsum";					//상품 가격
	private static final String EBAY_PRODUCT_PICTURE_SELECTOR 	= "#PicturePanel";				//상품 사진
	
	private static final String EBAY_PRODUCT_SPECIFICATIONS 	= "#viTabs_0_is";				//상품 사양
	private static final String EBAY_PRODUCT_DETAILS 			= "#desc_ifr"; 					//상품 상세
	
	public List<Map<String, Object>> process(List<String> urlList) {
		Document doc = null;
		Connection conn = null;
		List<Map<String, Object>> result = new ArrayList<Map<String, Object>>();
		
		for(String url : urlList) {			
			if(url.contains("http") || url.contains("https")) {				
				conn = Jsoup.connect(url);	//Jsoup 커넥션 생성
			}
			
			try {
				doc = conn.get();
				result.add(getDataList(doc));
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		
		return result;
	}
	
	public Map<String, Object> getDataList(Document document){
		Map<String, Object> dataMap = new HashMap<String, Object>();
		
		Elements selectsInfo = document.select(EBAY_PRODUCT_INFO_CARD_CLASS);			//select 메서드 안에 css selector를 작성하여 Elecments를 가져옴.
		Elements selectsDetail = document.select(EBAY_PRODUCT_DETAIL_CARD_CLASS);		
		
		for(Element select : selectsInfo) {
			String title = select.select(EBAY_PRODUCT_TITLE_CLASS).text();		//상품제목
			String optionKey = select.select("select").attr("name");			//옵션(제목)
			
			List<String> optionValues = new ArrayList<String>();				//옵션(항목)
			if(select.select("option").size() > 0) {
				for(Element value : select.select("option")) {
					optionValues.add(value.text());
				}
			}
			
			String price = select.select(EBAY_PRODUCT_PRICE_SELECTOR).text();	//상품가격
			if(price.replaceAll(" ", "").equals("")) {
				price = select.select("#mm-saleDscPrc").text();					//상품가격 안나오면 다른 태그로 찾음(세일가면 다른 태그로 쓰고 있음)
			}
			Double priceChange = null;
			if(!price.equals("")) {				
				priceChange = Double.valueOf(price.replaceAll("[^0-9.]", "").replaceAll(" ", "")); 	//소수점 제외 문자열 공백처리, 공백제거
				price = StringUtil.changePrice(priceChange * 1425.08);									//달러 환율만 넣었는데 환율 API 가져다 써야함			
			}
			
			List<String> photos = new ArrayList<String>();						//상품 이미지
			if(select.select(".ux-image-carousel img").size() > 0) {
				for(Element value : select.select("img")) {					
					if(!value.attr("src").equals("")) photos.add(value.attr("src"));
				}
			}
			
			dataMap.put("title", title);						//제목
			dataMap.put("optionKey", optionKey);				//옵션제목
			dataMap.put("optionValues", optionValues);			//옵션값
			dataMap.put("price", price);						//가격
			dataMap.put("photos", photos);						//이미지
		}
		
		for(Element select : selectsDetail) {
			String specifications	= select.select(EBAY_PRODUCT_SPECIFICATIONS).text();	//제품사양
			dataMap.put("specifications", specifications);	//제품사양
		}
		
		String detailsSrc = selectsDetail.select(EBAY_PRODUCT_DETAILS).attr("src");	//제품상세 iframe안에 있어서 src가져와서 정보 추출
		dataMap.put("details", getProductDetail(detailsSrc));				//제품상세
		
		return dataMap;
	}
	
	//상품 상세 가져오기
	//iframe안에 있어서 src가져와서 정보 추출
	public String getProductDetail(String detailUrl) {
		Document doc = null;
		Connection conn = null;
		
		if(detailUrl.contains("http") || detailUrl.contains("https")) {				
			conn = Jsoup.connect(detailUrl);	//Jsoup 커넥션 생성
		}
		
		try {
			doc = conn.get();
		} catch (IOException e) {
			e.printStackTrace();
		}
		
		return doc.select("#ds_div").html();
	}
	
	
}

 

 

결과물

https://youtu.be/NxUNUDvG-GU

 

https://github.com/entekk1111/miniProject

 

GitHub - entekk1111/miniProject: miniProject

miniProject. Contribute to entekk1111/miniProject development by creating an account on GitHub.

github.com

 

 

느낀점

처음엔 이베이 뿐만 아니라 다른 해외 쇼핑몰 사이트도 크롤링을 해보고 싶었다.

그러나 크롤링을 해보고 나니까 css선택자로만 가져오는 것이기 때문에 그냥 노가다인것 같다는 생각도 들었다.


 

 

 

REF

https://heekng.tistory.com/64

 

[Java] 크롤링 crawling, 셀레니움 Selenium

[Java] 크롤링 crawling, 셀레니움 Selenium 웹 크롤링의 정식 명칭은 Web Scraping이며, 웹 사이트에서 원하는 정보를 추출하는 것을 의미한다. 보통 웹 사이트는 HTML기반이기 때문에 정보를 추출할 페이

heekng.tistory.com

 

728x90
반응형