반응형
jsoup를 사용하여 자바 웹 크롤링을 해보았다.
이 사진의 url에서 (http://rank.ezme.net/diff) 의 다음,네이버,구글의 실시간 검색어를 모두 크롤링하여 중복을 제거하는 것을 수행하였다.
문제
-
시간대별로 (12시, 13시, 10시 등등 ) 원하는 시간을 선택하여 검색어 추출 ==> textfield 만들어서 입력값 함수 생성
-
검색어 중복을 제거(구글,네이버에 같은 검색어가 있으면 1개만 추출) ==> set 사용
-
여러시간을 선택할 때 원하는시간말고 선택한 다른시간의 검색어는 중복제거. (10,9,8 이라면 10이 원하는 시간 9,8시가 중복 제거해야할 시간 // 10시에 ''안녕'' , ''뭐해'', ''그래'' 가있고 9시에 ''안녕'' 8시에 ''뭐해''가 있다면 ''그래''만 출력해야한다.) ==> removeAll 함수 생성으로 중복 제거
처음에 jsoup라이브러리 없이 buffer로 사용했다가 ,, 안될것 같아서 jsoup라이브러리를 사용했다
.
jsoup.jar를 사이트에서 다운
properties > Java Build Path > Libraries > Add External JARs 로 jar 파일을 추가
추가 후 import 해서 사용
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
처음에 url을 불러와 html 을 크롤링 하는 코드
ArrayList<String> result = new ArrayList<String>(); //결과를 넣을 리스트
String inputValue = t; //입력받을 원하는 시간
//get html
String url = "http://rank.ezme.net/diff";
Document doc = Jsoup.connect(url).userAgent("Mozilla").get();
Elements elems = doc.select(".mdl-data-table"); // .mdl-data-table이 들어간 html 을 가져옴
Element elemtbody = elems.select("tbody").get(0);
int curTime = Integer.parseInt((elemtbody.select("tr.bg_info").first()).select("td").first().text().replace("시", ""));//가장 최근 시간
원하는 시간 값 체크
//get input value
List<Integer> list = queryString(curTime, inputValue); // 현재시간, 원한느 시간값 넣음
.....
//input value 처리 function
public static List<Integer> queryString(int curTime, String inputValue){
List<Integer> list = new ArrayList<Integer>();
if(inputValue == null || inputValue == ""){
return list;
} //inputValue값이 없으면 리턴
String[] sql = inputValue.split(" "); // 띄어쓰기 기준으로 split
for(int i=0; i< sql.length; i++){
if(curTime < Integer.parseInt(sql[i])){ //현재시간보다 큰값이면 수행x
continue;
}else{
list.add(Integer.parseInt(sql[i])); // 리스트에 원하는 시간 값 넣음
}
}
return list;
}
문제 3번작업 설정 , 중복제거(set이용)
//parseHTML
Set<String> realTimeSet = new HashSet<String>(); //중복제거를 위한 set
for(int i=0;i<list.size();i++){
if(i==0) { //맨 처음 값 기준 (원하는 값)
realTimeSet= parseHTML(curTime, list.get(i), elemtbody, realTimeSet);
System.out.println("parseHTML : " + realTimeSet.size() + ", " + realTimeSet.toString());
}else { // 나머지 중복 제거할 값
realTimeSet= removeAll(curTime, list.get(i), elemtbody, realTimeSet);
System.out.println("removeAll : " + realTimeSet.size() + ", " + realTimeSet.toString());
}
}
......
//웹 크롤링 function 더하기
public static Set<String> parseHTML(int curTime, int inputTime, Element elemtbody, Set<String> realTimeSet){
Element elemtr = null;
int timetable = (curTime - inputTime) * 10 ; // 전체 행이 10개이기 때문 11시에서 12시 사이는 10개에 해당
int j = 0;
for(int i=0 ; i<10 ; i++){ //현재 13시고 12시것을 가져오고 싶다면 10번째부터 20번째까지 값 가져오면 됨
j = i+timetable;
elemtr = elemtbody.select("tr").get(j); //tbody에 해당하는 tr 값의 j번째 값을 가져옴
if(j % 10 == 0){ //첫번째 줄은 'o시'가 있기 때문에 'o시,순위,1,2,3' 으로 이뤄져있다.
System.out.println(">> "+ elemtr.select("td").get(0).text());
realTimeSet.add(elemtr.select("td").get(2).text());
realTimeSet.add(elemtr.select("td").get(3).text());
realTimeSet.add(elemtr.select("td").get(4).text());
}else{ // 나머지는 '순위/ 검색어 1,2,3' 으로 이뤄져있음
realTimeSet.add(elemtr.select("td").get(1).text());
realTimeSet.add(elemtr.select("td").get(2).text());
realTimeSet.add(elemtr.select("td").get(3).text());
}
}
return realTimeSet;
}
//웹 크롤링 function 다른시간과 겹치는값 지우기
public static Set<String> removeAll(int curTime, int inputTime, Element elemtbody, Set<String> realTimeSet){
Element elemtr = null;
int timetable = (curTime - inputTime) * 10 ;
int j = 0;
for(int i=0 ; i<10 ; i++){
j = i+timetable;
elemtr = elemtbody.select("tr").get(j);
if(j % 10 == 0){
System.out.println(">> " +elemtr.select("td").get(0).text());
realTimeSet.remove(elemtr.select("td").get(2).text());
realTimeSet.remove(elemtr.select("td").get(3).text());
realTimeSet.remove(elemtr.select("td").get(4).text());
}else{
realTimeSet.remove(elemtr.select("td").get(1).text());
realTimeSet.remove(elemtr.select("td").get(2).text());
realTimeSet.remove(elemtr.select("td").get(3).text());
}
}
return realTimeSet;
}
완성된 소스 최종
package com.glab.app.service;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.URL;
import java.sql.Date;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
public class ParsingService {
/**
* 검색어를 파싱
* @param args
* @throws Exception
*/
public ArrayList<String> parsingKeyword(String t) throws Exception {
System.out.println("@@keyword reading start.@@ >> ");
ArrayList<String> result = new ArrayList<String>();
String inputValue = t;
//get html
String url = "http://rank.ezme.net/diff";
Document doc = Jsoup.connect(url).userAgent("Mozilla").get();
Elements elems = doc.select(".mdl-data-table");
Element elemtbody = elems.select("tbody").get(0);
int curTime = Integer.parseInt((elemtbody.select("tr.bg_info").first()).select("td").first().text().replace("시", ""));//가장 최근 시간
//get input value
List<Integer> list = queryString(curTime, inputValue);
//parseHTML
Set<String> realTimeSet = new HashSet<String>();
for(int i=0;i<list.size();i++){
if(i==0) {
realTimeSet= parseHTML(curTime, list.get(i), elemtbody, realTimeSet);
System.out.println("parseHTML : " + realTimeSet.size() + ", " + realTimeSet.toString());
}else {
realTimeSet= removeAll(curTime, list.get(i), elemtbody, realTimeSet);
System.out.println("removeAll : " + realTimeSet.size() + ", " + realTimeSet.toString());
}
}
Iterator<String> iterator = realTimeSet.iterator();
for(int i=0;i<realTimeSet.size();i++) {
result.add(iterator.next());
}
// result= realTimeSet;
return result;
}
//input value 처리 function
public static List<Integer> queryString(int curTime, String inputValue){
List<Integer> list = new ArrayList<Integer>();
if(inputValue == null || inputValue == ""){
return list;
}
String[] sql = inputValue.split(" ");
for(int i=0; i< sql.length; i++){
if(curTime < Integer.parseInt(sql[i])){
continue;
}else{
list.add(Integer.parseInt(sql[i]));
}
}
return list;
}
//웹 크롤링 function
public static Set<String> parseHTML(int curTime, int inputTime, Element elemtbody, Set<String> realTimeSet){
Element elemtr = null;
int timetable = (curTime - inputTime) * 10 ;
int j = 0;
for(int i=0 ; i<10 ; i++){
j = i+timetable;
elemtr = elemtbody.select("tr").get(j);
if(j % 10 == 0){
System.out.println(">> "+ elemtr.select("td").get(0).text());
realTimeSet.add(elemtr.select("td").get(2).text());
realTimeSet.add(elemtr.select("td").get(3).text());
realTimeSet.add(elemtr.select("td").get(4).text());
}else{
realTimeSet.add(elemtr.select("td").get(1).text());
realTimeSet.add(elemtr.select("td").get(2).text());
realTimeSet.add(elemtr.select("td").get(3).text());
}
}
return realTimeSet;
}
//웹 크롤링 function
public static Set<String> removeAll(int curTime, int inputTime, Element elemtbody, Set<String> realTimeSet){
Element elemtr = null;
int timetable = (curTime - inputTime) * 10 ;
int j = 0;
for(int i=0 ; i<10 ; i++){
j = i+timetable;
elemtr = elemtbody.select("tr").get(j);
if(j % 10 == 0){
System.out.println(">> " +elemtr.select("td").get(0).text());
realTimeSet.remove(elemtr.select("td").get(2).text());
realTimeSet.remove(elemtr.select("td").get(3).text());
realTimeSet.remove(elemtr.select("td").get(4).text());
}else{
realTimeSet.remove(elemtr.select("td").get(1).text());
realTimeSet.remove(elemtr.select("td").get(2).text());
realTimeSet.remove(elemtr.select("td").get(3).text());
}
}
return realTimeSet;
}
}
10, 9, 8시 입력시 10기준으로 9시8시것 중복제거 된 채로 나오게 된다.
반응형
'프로그래밍 언어 > JAVA' 카테고리의 다른 글
가비지컬렉션 (0) | 2020.12.04 |
---|---|
12. 입출력 작업하기 (0) | 2019.02.12 |
11. 예외 처리하기 (0) | 2019.02.12 |
10. 컬렉션 API활용하기 (0) | 2019.02.12 |
09. 기본 API활용하기 (0) | 2019.02.11 |