재밌고 어려운 IT를 이해해보자~!
Web Crawling 본문
웹 크롤링과 웹 스크래핑의 차이점
크롤링과 스크래핑은 ‘원하는 데이터를 모을 수 있다’는 점이 비슷하여 의미가 중복적이다. 하지만 웹 크롤링은 웹 페이지의 링크를 타고 계속해서 탐색을 이어나가는방식인 반면, 웹 스크래핑은 데이터 추출을 원하는 대상이 명확하여 특정 웹 사이트만을 추적한다는 차이점이 있다.
또한 웹 크롤링은 페이지를 모아 분류하고 검색 결과에 내가 찾는 키워드와 연관된 링크들만 모아 볼 수 있도록 작동한다. 하지만 웹 스크래핑은 상품의 가격, 주식 정보, 뉴스 등 원하는 데이터가 명확하며, 흩어져있는 해당 데이터를 자동으로 추출하여 전달한다.
웹 스크래핑은 웹 페이지의 내용을 추출하거나 분석하는 과정을 의미한다.. 특정 웹 페이지(단일)에서 필요한 정보를 수집하기 위해 HTML 구조를 파싱 하여 원하는 데이터를 추출하여 필요한 정보를 가져올 수 있으며 웹의 다양한 데이터를 자동으로 수집하고 이러한 수집된 정보(여러 웹의 데이터)를 통해 비교 및 분석이 가능하다.
이번에 배운 주재는 웹 크롤링이지만 가공하는 것을 제외하면 웹 스크래핑과 비슷한 느낌이다!
크롤링은
데이터를 많이 모아서, 원하는 output으로 정제·가공하는 작업이며, 빅데이터에서 많이 활용되는 기술이다.
웹으로부터 데이터를 많이 모아서 가공할 예정 url,target,webpage를알아야한다.
말 그대로 해당 URL은 "페이지"로 구성되어있으며 개발자가 페이지를 코드로 작성하면,
웹 브라우저라는 sw가 코드(페이지)를 해석해서 UI로 구현해서 보여준다.
*주의사항
우리는 페이지의 들어가서 개발자소스를 볼 수 있지만 개발자가 제공하고싶지 않은 정보들은 hide 되어있다.
따라서 웹크롤링을 연습하고 싶을땐 대부분의 소스가 open되어있는 웹페이지를 대상으로 연습하자.
또한 상업적목적이아닌, 학습목적이면 소스를 분석하고 데이터를 가져와 가공해도 괜찮다.
웹 페이지 정보를 JAVA에서는 Document라고 한다.
우리가 사용할 웹 페이지 정보(Document) 타입은 JAVA에서 기본제공 하지 않는다.
따라서 외부로부터 Document를 지원해줄수있는 .jar파일을 추가해야한다.
데이터베이스의 ojdbc6.jar 파일처 jsoup.jar을 다운받아 build path에 추가해주자.
웹페이지에서의 "요소" 는 element 라고하며 태그라고도 부른다.
하지만 그 둘은 차이가 있다.
HTML
태그와 요소의 차이점
HTML 태그(tags)와 HTML 요소(elements)는 자주 같은 단어로 사용된다. 하지만 엄밀히 말하면 다르다.
태그는 요소의 시작과 끝을 알리는 문법 기호이고 요소는 웹 페이지를 구성하는 성분이다. 태그는 요소와 동일어가 아니라 요소의 구성 요소, 부분 집합이다.
HTML 태그 ⊂ HTML 요소
위 그림에서 알 수 있듯이 태그와 요소는 다르다. 요소는 문서의 내용(contents)과 내용의 시작과 끝을 알리는 태그(tags), 그리고 태그의 동작을 제어하는 속성(attributes)으로 이루어져 있고, 태그는 요소의 구성 성분으로 콘텐츠의 시작과 끝을 알리는 일을 한다.
여기서 <p>와 </p>는 HTML 태그(여는 태그, 닫는 태그)이고 <p>Hello World</p>처럼 여는 태그, 콘텐츠, 닫는 태그가 모두 있어야 HTML 요소라고 불린다.
기술적 정의
HTML 태그는 소스 코드(source code)에서 요소의 시작과 끝을 표시하는 마크업(markup) 기호입니다. 반면, HTML 요소는 웹 브라우저가 문서를 구문 분석한 후에 만든 문서 객체 모델(Document Object Model, DOM)의 내부 표현입니다.
웹페이지를 코딩하는 언어는 HTML (Hypertext Markup Language)이며 이를 '마크업 언어'라 부르고 <> 를 사용한 태그로 이루어져있다.
따라서 내가 가져올 데이터가 "어떤 태그인가?"를 알아야한다.
영화 제목같은 것은 <strong> 태그에 존재한다.
<strong>태그란?
<strong> 태그는 텍스트의 중요성을 강조할 때 설정한다
일반적으로 텍스트는 굵게 표현이 된다. <strong> 태그는 다른 태그와 유사한 점이 있기 때문에 비교하며 적절한 곳에 사용해야 한다. 가령 <b> 태그와 <strong> 태그는 출력되는 모양이 같지만 <strong> 태그는 컨텐츠의 중요성을 강조하는 반면 <b> 태그는 텍스트의 주의를 끌기 위함이다.
태그(요소)들은 "속성"을 가질수있다.
id 속성 => 유일한 요소에게 부여하는 값
ex)로고, 검색창, ,,,
# 으로 표시
class 속성 => 여러 반복되는 요소에게 부여하는 값
ex) 영화 제목에게 붙는 title class 값
.으로 표시
JAVA 의 class와는 완전히 무관하다.
ex)
div#logo <div id = "logo">로고<div>
div.product <div class="product>상품명<div>
span.dt <span class="dt">설명<span>
a 태그(Tag)는 문서를 링크 시키기 위해 사용하는 태그(Tag)이다.
-사용법-
href : 연결할 주소를 지정 한다.
<a href= "URL 링크">URL</a>
target : 링크를 클릭 할 때 창을 어떻게 열지 설정 한다.
title : 해당 링크에 마우스 커서를 올릴때 도움말 설명을 설정 한다.
과제!
1. 웹에서 샘플될 만한 데이터를 끌어와서
2. DB에 저장하고
3. JAVA에서 Client로 COnsole에 전체목록출력을 통해 샘플 데이터 출력
애견용품의 제목과 가격을 데이터베이스에 저장하고 출력해보았다!
CTRL
package ctrl;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import model.DogfoodDAO;
import model.DogfoodDTO;
import view.VIEW;
public class CTRL {
private DogfoodDAO bDAO;
private VIEW view;
private DogfoodDTO bDTO;
public CTRL() {
bDAO = new DogfoodDAO();
bDTO = new DogfoodDTO();
view = new VIEW();
}
public void start() {
final String url = "https://www.dogpang.com/";
Document doc = null;
try {
doc = Jsoup.connect(url).get();
// Jsoup.connect(url) => connection 객체가 반환됨
// connection.get() => document 객체가 반환됨
// JDBC와 유사
} catch (IOException e) {
e.printStackTrace();
}
Elements elems = doc.select("strong.price");
Elements elems2 = doc.select("div.flex-contents");
Iterator<Element> itr = elems.iterator();
Iterator<Element> itr2 = elems2.iterator();
while (true) {
int action = view.inputAction();
if (action == 0) {
break;
} else if (action == 1) {
} else if (action == 2) {
}
else if (action == 3) {
while (itr.hasNext()) {
String str = itr.next().text();
String str2 = itr2.next().text();
str2 = str2.substring(0,30);
bDTO.setPrice(str);
// System.out.println(str3);
// bDTO.setTitle("A");
bDTO.setTitle(str2);
bDAO.insert(bDTO);
// System.out.println(str);
// System.out.println(str2);
}
} else if (action == 4) {
DogfoodDTO bDTO = new DogfoodDTO();
ArrayList<DogfoodDTO> datas = bDAO.selectAll(bDTO);
view.printDatas(datas);
} else if (action == 5) {
} else if (action == 6) {
}
}
}
}
3번을 눌러 저장하고 4번을 눌러서 출력하도록 작성했다.
한가지 아쉬운점은..VARCHAR의 Maxbyte가 80인거같다.
character set을 utf8 로 생성했다면 한 문자당 3byte를 차지하니 title이 다들어가지 않아 문자열을 잘랐다.
또 한가지의 문제점은..
소스를보면 div 태그의 class속성 안을보면 이름, 59%, 2,400원이 들어있고 div태그가 끝난다.
따라서 내가 별도로 출력해주려는 Strong class의 price 가 title에 같이 나오게 된다는 점이었다.
구선생님의 힘을빌려서 div 태그의 class속성을 iterator를 통해 순회하면서 매 순회마다 span의 태그중에 첫번째 값만 가져오라고 했더니 해결이 되었ㄷr... 힘들었다.
package ctrl;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import model.DogfoodDAO;
import model.DogfoodDTO;
import view.VIEW;
public class CTRL {
private DogfoodDAO bDAO;
private VIEW view;
private DogfoodDTO bDTO;
public CTRL() {
bDAO = new DogfoodDAO();
bDTO = new DogfoodDTO();
view = new VIEW();
}
public void start() {
final String url = "https://www.dogpang.com/";
Document doc = null;
try {
doc = Jsoup.connect(url).get();
// Jsoup.connect(url) => connection 객체가 반환됨
// connection.get() => document 객체가 반환됨
// JDBC와 유사
} catch (IOException e) {
e.printStackTrace();
}
Elements elems = doc.select("strong.price");
Elements elems2 = doc.getElementsByClass("flex-contents");
for (Element e : elems2) {
System.out.println(e);
}
Iterator<Element> itr = elems.iterator();
Iterator<Element> itr2 = elems2.iterator();
while (true) {
int action = view.inputAction();
if (action == 0) {
break;
} else if (action == 1) {
} else if (action == 2) {
}
else if (action == 3) {
while (itr.hasNext()) {
String str = itr.next().text();
String str2 = itr2.next().getElementsByTag("span").get(0).text();
// str2 = str2.substring(0,20);
bDTO.setPrice(str);
// System.out.println(str3);
// bDTO.setTitle("A");
if (str2.length()<25) {
bDTO.setTitle(str2);
bDAO.insert(bDTO);
}
// System.out.println(str);
// System.out.println(str2);
}
} else if (action == 4) {
DogfoodDTO bDTO = new DogfoodDTO();
ArrayList<DogfoodDTO> datas = bDAO.selectAll(bDTO);
view.printDatas(datas);
} else if (action == 5) {
} else if (action == 6) {
}
}
}
}
원하는 데이터를 잘 가져왔다 !! 굿 :D
'코리아IT핀테크과정' 카테고리의 다른 글
JavaScript (3) | 2024.01.04 |
---|---|
WebApp, HTML 1 (0) | 2023.12.27 |
웹서버 프로그래밍 시험 오답노트 (0) | 2023.12.21 |
MVC with Oracle 2 (0) | 2023.12.20 |
MVC with Oracle 1 (0) | 2023.12.19 |