@markdown
# Java 웹 크롤러 만들기
____
- Java에서는 Jsoup HTML 파싱하는 라이브러리를 사용하여 크롤링 할 수 있다.
- Python에서 `BeautifulSoup` 라이브러리와 비슷하다.
- `selector`를 통해서 HTML 원하는 태그의 텍스트, 속성, 링크 등을 가져올 수 있다.
- `Java 1.5`, `Scala`, `Android`, `OSGi`, `Lambda`, `Google App Engine`에서 동작하는 라이브러리이다.
- 2017.05.31일 기준 1.10.2 버전이 최신버전임
## Jsoup 라이브러리 추가하기
_____
- Eclipse에서 `.jar` 라이브러리를 추가하기 위해 `jsoup-1.10.2.jar` core library를 다운로드 한다.
- 라이브러리 다운 : [https://jsoup.org/download](https://jsoup.org/download)
![](https://cloud.githubusercontent.com/assets/12658717/26616941/4228de70-460d-11e7-909b-9bb7772cdec8.png)
- Eclipse Java project에서 Java Build Path - Add External JARs로 Jsoup.jar 라이브러리를 추가해준다.
- 라이브러리 추가 하면 `Package Explorer`에 `Referenced Libraries` 폴더가 생성되면서 `Jsoup` 라이브러리가 import 된다.
- 이후에 `.java` 파일에서 import 후 사용할 수 있다.
<br>
## Jsoup 사용하기
_____
- 간단한 파싱을 위해 네이버 뉴스에서 오늘의 핫뉴 부분을 파싱해본다.
- 구글 크롬 개발자 도구를 통해 해당 뉴스 부분의 제목이나 class id를 확인 할 수 있다.
- 개발자 도구를 통해 파싱하고 싶은 부분의 class id, tag 등을 먼저 찾는다.
- Jsoup.connect() : 파싱할 웹 사이트 URL을 입력해 파싱 데이터가 Document 형태로 반환된다.
```
Document doc = Jsoup.connect("http://news.naver.com/").get();
```
- `doc` 객체에는 아래 스샷과 같이 파싱한 `HTML` 웹 페이지 코드가 저장되어 있다.
![](https://cloud.githubusercontent.com/assets/12658717/26622350/159644de-4625-11e7-8b5f-a4617e516e9c.png)
### select() 사용법
____
- 클래스 이름 ` . ` 사용, ID `#` 사용
- `class` 이름이 `main_hotissu`인 항목만 가져오기
```
doc.select(".main_hotissu");
```
- `id`가 `main`인 항목 가져오기
```
doc.select("#main");
```
- `class`명이 `main_hotissu` 항목에서 `<a>` 태그만 파싱하기
```
doc.select(".main_hotissu a");
```
<br>
```
doc.select(".main_hotissu").get(0);
```
- `select()` 결과 : Elements 반환, 결과 값이 1개 일때 사용
- `select().get(index)` 결과 :Element 반환, 파싱한 태그의 결과 값이 여러개일때 사용
<br>
### Element.toString()
____
```
Document doc = Jsoup.connect("http://news.naver.com/").get();
Element hotNews = doc.select("ul.mlist2").get(0);
System.out.println(hotNews.toString());
```
```
실행결과 <ul> 태그 Element 한개, 파싱한 값 전체가 반환된다.
<ul class="mlist2">
<li> <a href="http://news.naver.com/main/hotissue/sectionList.nhn?mid=hot&sid1=100&cid=1064070&iid=26055409&ptype=1064256#1064256" class="nclicks(hot.text)" title="[이낙연 총리후보자 인준은]
한국당 "丁의장 방문..이낙연 인준안 상정 철회 요구할 것"">[이낙연 총리후보자 인준은] 한국당 "丁의장 방문..이낙연 인준안 상...</a><img src="http://static.news.naver.net/image/news/2009/ico_photo.gif" width="13" height="13" alt="포토" title="포토"><span class="writing">이데일리</span> </li>
<li> <a href="http://news.naver.com/main/hotissue/sectionList.nhn?mid=hot&sid1=100&cid=1064070&iid=2133041&ptype=1064968#1064968" class="nclicks(hot.text)" title="['문재인 대통령' 행보]
文대통령 "재조해양"..'세월호' '새만금' '해운산업' 강조">['문재인 대통령' 행보] 文대통령 "재조해양"..'세월호' '새만금' '해운산업...</a><span class="writing">이데일리</span> </li>
<li> <a href="http://news.naver.com/main/hotissue/sectionList.nhn?mid=hot&sid1=100&cid=1064070&iid=49397904&ptype=1064407#1064407" class="nclicks(hot.text)" title="['文 정부' 국정기획자문위]
국정기획위 "국정원에 철저한 개혁 주문…의지 확인" (종합2보)">['文 정부' 국정기획자문위] 국정기획위 "국정원에 철저한 개혁 주문...</a><img src="http://static.news.naver.net/image/news/2009/ico_photo.gif" width="13" height="13" alt="포토" title="포토"><span class="writing">뉴스1</span> </li>
<li> <a href="http://news.naver.com/main/hotissue/sectionList.nhn?mid=hot&sid1=100&cid=1064070&iid=24864819&ptype=1064552#1064552" class="nclicks(hot.text)" title="['인사청문·검증' 본격화]
김동연 경제부총리 후보자 인사청문회 6월 7일 실시">['인사청문·검증' 본격화] 김동연 경제부총리 후보자 인사청문회 6...</a><img src="http://static.news.naver.net/image/news/2009/ico_photo.gif" width="13" height="13" alt="포토" title="포토"><span class="writing">뉴스1</span> </li>
<li> <a href="http://news.naver.com/main/hotissue/sectionList.nhn?mid=hot&sid1=100&cid=1064070&iid=49513458&ptype=1065003#1065003" class="nclicks(hot.text)" title="[文대통령, 장관 후보자 4명 발표]
'의원 4명' 장관 발탁… 인사 암초 정면 돌파">[文대통령, 장관 후보자 4명 발표] '의원 4명' 장관 발탁… 인사 암초...</a><img src="http://static.news.naver.net/image/news/2009/ico_photo.gif" width="13" height="13" alt="포토" title="포토"><span class="writing">서울신문</span> </li>
</ul>
```
<br>
### Element.text()
____
```
Document doc = Jsoup.connect("http://news.naver.com/").get();
Element hotNews = doc.select("ul.mlist2").get(0);
Elements news = hotNews.select("li");
for(Element e : news){
System.out.println(e.text());
}
System.out.println(e.getElementsByAttribute("href").attr("href"));
```
```
실행결과 : 핫 뉴스 부분의 제목만 파싱한 결과
[이낙연 총리후보자 인준은] '이낙연 인준' 국회 본회의 지연…한국당...뉴스1
['文 정부' 차관 인선] 文정부 첫 차관 인선…기재·교육·국토·외교...뉴스1
['문재인 대통령' 행보] 文대통령 "재조해양"..'세월호' '새만금' '해운산업...이데일리
['文 정부' 국정기획자문위] 국정기획위 "국정원에 철저한 개혁 주문...뉴스1
['인사청문·검증' 본격화] 김동연·강경화 인사청문회, 내달 7일 ...머니투데이
```
<br>
```
for(Element e : news){
System.out.println(e.getElementsByAttribute("href").attr("href"));
}
```
```
실행결과 : 핫 뉴스 부분의 url 파싱 결과
http://news.naver.com/main/hotissue/sectionList.nhn?mid=hot&sid1=100&cid=1064070&iid=26055976&ptype=1064256#1064256
http://news.naver.com/main/hotissue/sectionList.nhn?mid=hot&sid1=100&cid=1064070&iid=2338295&ptype=1065081#1065081
http://news.naver.com/main/hotissue/sectionList.nhn?mid=hot&sid1=100&cid=1064070&iid=2133041&ptype=1064968#1064968
http://news.naver.com/main/hotissue/sectionList.nhn?mid=hot&sid1=100&cid=1064070&iid=49397904&ptype=1064407#1064407
http://news.naver.com/main/hotissue/sectionList.nhn?mid=hot&sid1=100&cid=1064070&iid=24864853&ptype=1064552#1064552
```
<br>
### text() vs toString()
____
- `text()`로 해당 `li` 태그의 `title` 값을 얻어올 수 있다.
- `getElementsByAttribute("href").attr("href")`로 href 태그 값을 얻어와 해당 기사 URL을 얻어올 수 있다.
- 기사 URL을 다시 `Jsoup.connect()`해 링크를 들어간다면, 기사 본문을 크롤링 할 수 있을 것이다.
- `element.toString()`은 파싱한 태그 값 전체를 출력하고, `element.text()`는 파싱한 태그의 title 값만 출력할 수 있다.
<br>
### Document.select().get()
____
```
Element hotNews = doc.select("ul.mlist2").get(0);
```
- 부분에서 .get(1)의 값을 가져오면, 다른 연예, 사회 등 부분의 뉴스 정보를 가져온다.
- mlist2라는 이름을 사용하는 여러 부분이기 때문이다.
'Java' 카테고리의 다른 글
Java - AutoCloseable, Network 프로그래밍 (0) | 2017.05.29 |
---|---|
Java - MVC, 정적 쿼리, 동적 쿼리 (1) | 2017.05.21 |
Java - JDBC 사용 및 DB 연결 (0) | 2017.05.20 |
Java 문법 - Generic, Collection, IO (0) | 2017.05.10 |
Java 문법 - String, Arrays, Thread (0) | 2017.05.08 |