본문 바로가기

Java

Java - 웹 크롤러 만들기(1)

@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&amp;sid1=100&amp;cid=1064070&amp;iid=26055409&amp;ptype=1064256#1064256" class="nclicks(hot.text)" title="[이낙연 총리후보자 인준은]

한국당 &quot;丁의장 방문..이낙연 인준안 상정 철회 요구할 것&quot;">[이낙연 총리후보자 인준은] 한국당 "丁의장 방문..이낙연 인준안 상...</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&amp;sid1=100&amp;cid=1064070&amp;iid=2133041&amp;ptype=1064968#1064968" class="nclicks(hot.text)" title="['문재인 대통령' 행보]

文대통령 &quot;재조해양&quot;..'세월호' '새만금' '해운산업' 강조">['문재인 대통령' 행보] 文대통령 "재조해양"..'세월호' '새만금' '해운산업...</a><span class="writing">이데일리</span> </li> 

<li> <a href="http://news.naver.com/main/hotissue/sectionList.nhn?mid=hot&amp;sid1=100&amp;cid=1064070&amp;iid=49397904&amp;ptype=1064407#1064407" class="nclicks(hot.text)" title="['文 정부' 국정기획자문위]

국정기획위 &quot;국정원에 철저한 개혁 주문…의지 확인&quot; (종합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&amp;sid1=100&amp;cid=1064070&amp;iid=24864819&amp;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&amp;sid1=100&amp;cid=1064070&amp;iid=49513458&amp;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라는 이름을 사용하는 여러 부분이기 때문이다.