네트워크 / URL / Jsoup

준동이·2023년 4월 13일
0

복습

GUI - Character(Text)

명령 프롬프트(dir...) = Terminsal이라고 한다

GUI - Graphic(2D -> 3D)

그래픽을 사용하여 사용자와 대화
2D, 3D 기반
각 언어마다 틀림

공식 OpenAPI

공공기관 - data.co.kr
google = developer.google.com
다음 / 네이버 - developers.naver.com
영화관련 정보 - kobis.or.kr/

데이터크롤링(스크래핑) <- 네트워크 필요

크롤링은 개인 혹은 단체에서 필요한 데이터가 있는 웹(Web)페이지의 구조를 분석하고 파악하여 긁어온다.
여기서 긁어온다는 의미는 모두 그대로 가져오는 것을 말한다.

text(csv)
xml
json

네트워크

인트라넷 - 사내망

192.168.XXX.XXX
라우터 내부 인트라넷, 외부 인터넷
라우터(통신사 공유기)

인터넷 - 외부망

그외
IP(Internet Protocol에서 규정)

IP

전세계의 컴퓨터(네트워크 카드)
IPv4 -> IPv6

네트워크 카드의 위치 / 고유정보(MAC)
컴퓨터간 데이터를 전송할 수 있는 컴퓨터의 물리적 주소
하드웨어 주소 또는 물리적 주소로도 불리는 MAC(Media Access Control:매체 접근 제어) 주소는 네트워크 카드에 대한 고유 식별자를 말한다.
주민등록번호와 같이 MAC 주소 역시 변경할 수 없다.



네트워크 카드와 + 프로그램

Port : 컴퓨터에서의 포트(port)란 외부의 다른 장비와 접속하기 위한 플러그와 같은 것을 의미.

만약 웹브라우저를 이용하여 인터넷상에 있는 서버에 접속할 때 컴퓨터에 있는 웹브라우저 프로그램과 서버에 있는 웹서버 프로그램간을 연결해주는 플러그와 같은 역할을 하는 것이 포트

외부에서 프로그램에 접근

  1. 프로토콜(전송규약)을 알아야한다
  2. IP
  3. port
    를 알아야 외부에서 접근이 가능하다

Well Known Port (잘 알려진 포트)

프로토콜과 포트는 일종의 기본값.
기본값은 생략이 가능하다.
http - html문서를 전송하는것 80포트가 기본
https - 443포트 사용
mail - 25번 포트 사용
mariadb - 3306포트 사용

ipconfig / ifconfig/all / ping(컴퓨터가 살아있는지 확인) / tracert

ping : ping 아이피 입력
tracert 주소 : 경로 추적 / 경로 값 표시 (https://gsuite.tools/traceroute)

"*" 표시는 막아놓은 것

netstat -an : 포트가 개방돼있는 상황을 알 수 있다.(포트의 개방경로)



자바를 이용하여 네트워크 프로그램 짤 때 알아둘것

프로그램간의 역할

  • CS 프로그램 (서버 하나에 클라이언트 여러개가 묶일 수 있다.)
    클라이언트(요청자) <- 네트워크 -> 서버(응답) 으로 분활해서 처리
    Client로 부터 받은 요청을 Server가 처리하고 다시 Client에게 결과를 돌려주는 방식.
    브라우저와 웹서버(톰캣)의 관계
    mysql 명령어(Heidi)와 mariadb서비스와의 관계가 클라이언트 서버



P2P(Peer to Peer)

클라이언트와 서버역할을 동시에 하는 것.
만들어진것이 블록체인(P2P를 통해)

내가 클라이언트이자 서버 역할을 한다. 누군가에 의해 요청 / 받아들이기 할 수 있음.. (체인형식), 어느 하나가 죽더라도 다른곳에서 연결 가능



InetAddress : 아이피 정보 가져오기 클래스

import java.net.InetAddress;
import java.net.UnknownHostException;

public class NetworkEx01 {
	public static void main(String[] args) {
		// IP정보 <- 도메인
		// 네트워크는 java.net 패키지 사용
		
		try {
			// daum.net에 대한 아이피 정보 가져오기
			InetAddress inetAddress1 = InetAddress.getByName("www.daum.net");
			System.out.println(inetAddress1.getHostAddress());
			System.out.println(inetAddress1.getHostName());
			
			// 모든 아이피를 보기
			InetAddress[] inetAddresses = InetAddress.getAllByName("www.naver.com");
			for(InetAddress inetAddress : inetAddresses) {
				System.out.println(inetAddress.getHostAddress());
			}
			
		} catch (UnknownHostException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}



URL클래스 : URL 정보를 가지고있는 클래스

  1. URL 클래스는 URL을 추상화 하여 만든 클래스.

  2. URL 클래스는 final 클래스로 되어 있기 때문에 상속하여 사용할 수 없다.

  3. 모든 생성자는 MalformedURLException 예외를 발생하기 때문에 반드시 예외처리를 해야 한다.

url 구성 예시

https://search.naver.com:437/search.naver?where=nexearch&sm=top_hty&fbm=1&ie=utf8&query=covid

https - 프로토콜
search.naver.com:443 - 도메인(아이피), 포트
search.naver - 경로 / 파일명
where=nexearch&sm=top_hty&fbm=1&ie=utf8&query=covid - 쿼리 (키와 값으로 나뉨)
=> 문자열 분석하여 알아냄 => 불편하니까 url클래스를 사용

url 정보 출력

import java.net.MalformedURLException;
import java.net.URL;

public class NetworkEx02 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		try {
			String strUrl = "https://search.naver.com:443/search.naver?where=nexearch&sm=top_hty&fbm=1&ie=utf8&query=covid";
			
			// url 클래스화
			URL url = new URL(strUrl);
			
			// 정보 추출
			System.out.println(url.getProtocol());
			System.out.println(url.getHost());
			System.out.println(url.getPort());
			System.out.println(url.getPath());
			System.out.println(url.getQuery());
			
		} catch (MalformedURLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

}



url통해 html문서 접근

url 클래스 -> 웹서버 -> 웹서버에서 html

접속은 url
읽어오는것은 IO로 한다.



html문서 접근

inputstream 사용으로 한글이 깨져서 나온다

import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;

public class NetworkEx03 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
        // inputstream 써서 한글이 깨져서 나온다.
		InputStream is = null;
		
		try {
			// Network 부분 / 접속
			URL url = new URL("https://m.daum.net");
            
            // openStream() : 사이트 데이터 읽기 
			is = url.openStream();
			
			// IO 부분 / 읽기
			int data = 0;
			while((data = is.read()) != -1) {
				System.out.print((char)data);
			}
			System.out.println();
		} catch (MalformedURLException e) {
			// TODO Auto-generated catch block
			System.out.println("[에러] : " + e.getMessage());
		} catch (IOException e) {
			// TODO Auto-generated catch block
			System.out.println("[에러] : " + e.getMessage());
		} finally {
			if(is != null) try {is.close();} catch(IOException e) {}
		}
	}

}

해당 링크의 html문서 읽어옴



한글이 깨져셔 BuffereReader로 정상출력하기

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;

public class NetworkEx03 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		BufferedReader br = null;
		
		try {
			// Network 부분
			URL url = new URL("https://m.daum.net");
			br = new BufferedReader(new InputStreamReader(url.openStream()));
			
			// IO 부분
			
			String line = "";
			while((line = br.readLine()) != null) {
				System.out.print(line);
			}
			System.out.println();
		} catch (MalformedURLException e) {
			// TODO Auto-generated catch block
			System.out.println("[에러] : " + e.getMessage());
		} catch (IOException e) {
			// TODO Auto-generated catch block
			System.out.println("[에러] : " + e.getMessage());
		} finally {
			if(br != null) try {br.close();} catch(IOException e) {}
		}
	}

}



다음 뉴스 html문서의 li 빼오기

url.openStream() : 사이트 데이터 읽어오기
뉴스 페이지의 ul 시작부터 ul 끝까지의 데이터를 출력

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;

public class NetworkEx05 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		BufferedReader br = null;
		
		try {
			// Network 부분
			URL url = new URL("https://news.daum.net");
			br = new BufferedReader(new InputStreamReader(url.openStream()));
			
			// IO 부분
			String line = "";
			
			// 시작과 끝 나타내기
			boolean flag = false;
			while((line = br.readLine()) != null) {
            	 /* 밑의 것들로 사용 가능
				 equals
				 contains(포함) / startWith / endWith
				 indexOf
                 */
				// <ul class="list_newsissue"> 시작지점
				// </ul> 끝나는지점
				
				if(line.contains("<ul class=\"list_newsissue\">")) {
					flag = true;
				}
				
				if(line.contains("</ul>")) {
					flag = false;
				}
				
				if(flag) {
					System.out.println(line);
				}
			} 
			System.out.println();
		} catch (MalformedURLException e) {
			// TODO Auto-generated catch block
			System.out.println("[에러] : " + e.getMessage());
		} catch (IOException e) {
			// TODO Auto-generated catch block
			System.out.println("[에러] : " + e.getMessage());
		} finally {
			if(br != null) try {br.close();} catch(IOException e) {}
		}
	}

}

ul태그 시작부터 /ul까지 출력



특정부분 출력

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;

public class NetworkEx05 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		BufferedReader br = null;
		
		try {
			// Network 부분
			URL url = new URL("https://news.daum.net");
			br = new BufferedReader(new InputStreamReader(url.openStream()));
			
			// IO 부분
			String line = "";
			
			// 시작과 끝 나타내기
			boolean flag = false;
			while((line = br.readLine()) != null) {
				// equals
				// contains / startWith / endWith
				// indexOf
				// <ul class="list_newsissue"> 시작지점
				// </ul> 끝나는지점
				
				//  class="link_txt" data-tiara-layer="article_main"
				// </a>
				if(line.contains(" class=\"link_txt\" data-tiara-layer=\"article_main\"")) {
					flag = true;
				}
				
				if(line.contains("</a>")) {
					flag = false;
				}
				
				if(flag) {
                
					// 한 줄을 또 건너뛰어서 코드부분은 없이 제목만 출력되게 함
					System.out.println(br.readLine().trim());
				}
			} 
			System.out.println();
		} catch (MalformedURLException e) {
			// TODO Auto-generated catch block
			System.out.println("[에러] : " + e.getMessage());
		} catch (IOException e) {
			// TODO Auto-generated catch block
			System.out.println("[에러] : " + e.getMessage());
		} finally {
			if(br != null) try {br.close();} catch(IOException e) {}
		}
	}

}



참고 - 상태코드



URLConnection / HttpURLConnection 클래스

URLopenConnection

Java애플리케이션과 URL간의 연결 관련한 모든 클래스의 수퍼클래스.
일반적인 URL 에 대한 API제공.
추상클래스로 새 인스턴스를 직접 만들 수 없음.
URL객체에서 연결을 통해 URLConnection의 인스턴스를 얻음.

URL 객체생성 -> URL에서 URLConnection객체 얻기
URLConnection 인스턴스는 URL객체의 openConnection()메소드 호출에 의해 얻어진다.

// URLConnection 인스턴스 얻기
ex) URLConnection urlCon = url.openConnection();



URLConnection으로 전체 소스 읽어오기

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;

public class NetworkEx06 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		BufferedReader br = null;
		
		try {
       		// URLConnection 인스턴스 얻기
			URLConnection conn = new URL("https://news.daum.net").openConnection();
            
			br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
			
			String line = null;
			while((line = br.readLine()) != null) {
				System.out.println(line);
			}
		} catch (MalformedURLException e) {
			// TODO Auto-generated catch block
			System.out.println("[에러] : " + e.getMessage());
		} catch (IOException e) {
			// TODO Auto-generated catch block
			System.out.println("[에러] : " + e.getMessage());
		} finally {
			if(br != null) try {br.close();} catch(IOException e) {}
		}
	}

}



HttpURLConnection - URLConnection을 구현한 클래스

웹을 통해 데이터를 주고 받는데 사용됨.
데이터 타입이나 길이는 거의 제한이 없음.
주로 미리 길이를 알지 못하는 스트리밍 데이터를 주고 받는데 사용됨.
URLConnection 클래스와 마찬가지로 직접 객체 생성 불가능

http URL을 사용하는 URL 객체의 openConnection() 메소드가 리턴하는 URLConnection객체는 HttpURLConnection의 인스턴스가 될 수 있기 때문에 리턴된 URLConnection을
다음처럼 HttpURLConnection으로 캐스팅해서 사용한다.

// HttpURLConnection의 객체 생성
ex) HttpURLConnection conn = (HttpURLConnection) url.openConnection();



HttpURLConnection으로 전체 소스 읽어오기 / 상태코드 확인

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;

public class NetworkEx06 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		BufferedReader br = null;
		
		try {
//			URLConnection conn = new URL("https://news.daum.net").openConnection();
			HttpURLConnection conn = (HttpURLConnection)  new URL("https://news.daum.net").openConnection();
			
			// 코드값 출력
            // getResponseCode() : 응답코드
			int responseCode = conn.getResponseCode();
			System.out.println(responseCode);
			
            /*
            conn.getInputStream()이 int 형이여서 InputStreamReader 로 문자로 변환 후 
            BufferedReader로 헌꺼번에 읽는다.
            */
			br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
			
			String line = null;
			while((line = br.readLine()) != null) {
				System.out.println(line);
			}
		} catch (MalformedURLException e) {
			// TODO Auto-generated catch block
			System.out.println("[에러] : " + e.getMessage());
		} catch (IOException e) {
			// TODO Auto-generated catch block
			System.out.println("[에러] : " + e.getMessage());
		} finally {
			if(br != null) try {br.close();} catch(IOException e) {}
		}
	}

}

정상출력 - 200 (OK - 요청 성공)

밑의 내용처럼 입력했을때 뜨는 에러 - 404 (Not Found - 존재하지 않는 리소스에 대한 요청)



if문으로 에러처리

new URL("https://news.daum.net/text.html") 로 에러를 발생시켰을 때 에러처리

			// 에러처리
        try {
			HttpURLConnection conn = (HttpURLConnection) new URL("https://news.daum.net/text.txt").openConnection();
			
			int responseCode = conn.getResponseCode();
			System.out.println(responseCode);
            
			if (conn.getResponseCode() == HttpURLConnection.HTTP_OK) {
				br = new BufferedReader(new InputStreamReader(conn.getInputStream()));

				String line = null;
				while ((line = br.readLine()) != null) {
					System.out.println(line);
				}
			} else {
				System.out.println("접속에러");
			}



정상 출력 / 좀 더 자세한 정보 출력하기

getRequestMethod() : 요청 방식
getResponseCode() : 응답 코드
getResponseMessage() : 응답 메세지


			// 코드값 출력
            // getResponseCode() : 응답코드
			int responseCode = conn.getResponseCode();
			System.out.println(responseCode);
            
if (conn.getResponseCode() == HttpURLConnection.HTTP_OK) {
				
				// 좀 더 자세한 정보 출력
				System.out.println(conn.getRequestMethod());
                
                // getResponseMessage() : 응답 메세지
				System.out.println(conn.getResponseMessage());

				br = new BufferedReader(new InputStreamReader(conn.getInputStream()));

				String line = null;
				while ((line = br.readLine()) != null) {
					System.out.println(line);
				}
			} else {
				System.out.println("접속에러");
			}

1은 responseCode 출력
2는 conn.getResponseMessage()
1과 2는 다른 의미 ? 왜 ?



에러를 만들고 에러결과 보기

			// 코드값 출력(에러)
			 int responseCode = conn.getResponseCode();

			// 에러처리
			if (conn.getResponseCode() == HttpURLConnection.HTTP_OK) {
				
				// 좀 더 자세한 정보 출력
				System.out.println(conn.getRequestMethod());
				System.out.println(conn.getResponseMessage());

				br = new BufferedReader(new InputStreamReader(conn.getInputStream()));

				String line = null;
				while ((line = br.readLine()) != null) {
					System.out.println(line);
				}
			} else {
            	// 에러 출력
//				System.out.println("접속에러");
				System.out.println(conn.getRequestMethod());
				System.out.println(conn.getResponseMessage());
				System.out.println(responseCode);
			}

1 = System.out.println(conn.getResponseMessage())
2 = System.out.println(responseCode)
1과 2는 다른 차이점이 있다는거같은데 똑같이 뜬다 .. 에러 자체가 404 (Not Found)에러라서 똑같이 뜨는건가

responseCode() 설명

getResponseMessage() 설명



Image 데이터 가져오기

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;

public class NetworkEx07 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		// BufferedReader - Reader와 Writer는 문자단위이기때문에 사용 x
		// BufferedInputStream / BufferedOutputStream 써야한다
		BufferedInputStream bis = null;
		BufferedOutputStream bos = null;

		try {
			HttpURLConnection conn = (HttpURLConnection) new URL(
					"https://t1.daumcdn.net/daumtop_chanel/op/20200723055344399.png").openConnection();

				bis= new BufferedInputStream(conn.getInputStream());
				bos = new BufferedOutputStream(new FileOutputStream("./daum.png"));

				int data = 0;
				while ((data = bis.read()) != -1) {
					bos.write(data);
				}
				System.out.println("다운로드 완료");
			
		} catch (MalformedURLException e) {
			// TODO Auto-generated catch block
			System.out.println("[에러] : " + e.getMessage());
		} catch (IOException e) {
			// TODO Auto-generated catch block
			System.out.println("[에러] : " + e.getMessage());
		} finally {
			if (bos != null)try {bos.close();} catch (IOException e) {}
			if (bis != null)try {bis.close();} catch (IOException e) {}
		}
	}

}



만들어보기

import java.awt.EventQueue;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;

import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.border.EmptyBorder;

public class ImageViewerEx01 extends JFrame {

	private JPanel contentPane;
	private JTextField textField1;
	private JTextField textField2;
	private JScrollPane scrollPane;
	private JLabel lbl;

	/**
	 * Launch the application.
	 */
	public static void main(String[] args) {
		EventQueue.invokeLater(new Runnable() {
			public void run() {
				try {
					ImageViewerEx01 frame = new ImageViewerEx01();
					frame.setVisible(true);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
	}

	/**
	 * Create the frame.
	 */
	public ImageViewerEx01() {
		setResizable(false);
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setBounds(100, 100, 800, 600);
		contentPane = new JPanel();
		contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));

		setContentPane(contentPane);
		contentPane.setLayout(null);
		
		textField1 = new JTextField();
		textField1.setText("https://");
		textField1.setBounds(12, 10, 313, 21);
		contentPane.add(textField1);
		textField1.setColumns(10);
		
		textField2 = new JTextField();
		textField2.setText( new File(".").getAbsolutePath().replaceAll( "\\\\", "/" ) + "/" );
		textField2.setBounds(12, 41, 313, 21);
		contentPane.add(textField2);
		textField2.setColumns(10);
		
		JButton btn1 = new JButton("저장");
		btn1.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent e) {
				BufferedInputStream bis = null;
				BufferedOutputStream bos = null;
				
				try {
					HttpURLConnection conn = (HttpURLConnection)
							new URL("https://t1.daumcdn.net/daumtop_chanel/op/20200723055344399.png").openConnection();
					
					
					bis = new BufferedInputStream(conn.getInputStream());
					bos = new BufferedOutputStream(new FileOutputStream("./daum4.png"));
					
					int data = 0;
					while((data = bis.read()) != -1) {
//						bos.write(data);
						lbl.setIcon(new ImageIcon("./daum4.png"));
					}
				} catch (MalformedURLException e1) {
					// TODO Auto-generated catch block
					System.out.println("[에러] : " + e1.getMessage());
				} catch (FileNotFoundException e1) {
					// TODO Auto-generated catch block
					System.out.println("[에러] : " + e1.getMessage());
				} catch (IOException e1) {
					// TODO Auto-generated catch block
					System.out.println("[에러] : " + e1.getMessage());
				} finally {
					if (bos != null)try {bos.close();} catch (IOException e1) {}
					if (bis != null)try {bis.close();} catch (IOException e1) {}
				}
				
			}
		});
		btn1.setBounds(337, 9, 97, 53);
		contentPane.add(btn1);
		
		scrollPane = new JScrollPane();
		scrollPane.setBounds(12, 72, 422, 229);
		contentPane.add(scrollPane);
		
		lbl = new JLabel("");
		scrollPane.setViewportView(lbl);
	}
}



Jsoup

https://jsoup.org/
jsoup-1.15.4.jar 다운

jsoup은 자바 언어로 HTML을 다루는 쉽고, 강력한 기능을 제공

Java html parser 로 html 형식의 string 을 java 에 넘겨주면 java에서 사용할 수있는 DOM 객체로 만들어 주는 parser.

웹페이지를 읽어들이는 기능을 하는 lib 는 아니다.

Document 객체는 웹 페이지 그 자체를 의미.
웹 페이지에 존재하는 HTML 요소에 접근하고자 할 때는 반드시 Document 객체부터 시작해야 한다.

Jsoup 주요 메서드

/* HTML을 읽어온 String을 Jsoup으로 변환시킨 것.
변환시키는 이유는 URL로 부터 웹 페이지를 앍어와서 알아서 DOM 객체로 변환해 주는
"Jsoup.parse(String url, int timeoutMillisecons)" api가 있는데,
Jsoup은 네트워크 라이브러리는 아니여서 그 api는 추천하지 않고,
네트워크 전용 라이브러리로 HTML을 읽어온 다음, 읽어온 String을 Jsoup으로 
변환해 주는 방법을 추천한다.
방법 :  
    String html = ...(html문서)
    Document doc = Jsoup.parse(html)
*/

String data = br.readLine();
Document doc = Jsoup.parse(data);
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

public class JsoupEx01 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		String html = "<html>"
				+ "<head><title>First parse</title></head>"
				+ "<body>"
				+ "<p>Parsed HTML into a doc.</p>"
				+ "<p>Parsed HTML into a doc.</p>"
				+ "</body>"
				+ "</html>";
		 
		// DOM 객체로 만들기 / Tree처럼 됨
		// HTML을 읽어왔다면 jsoup document 객체로 변환시키는 방법
        // HTML을 읽어온 String을 Jsoup으로 변환.
		Document doc = Jsoup.parse(html);
		System.out.println(doc);
		System.out.println();
		
		// 타이틀 내용 보기
		System.out.println(doc.title());
		System.out.println();
		
		// 특정한 태그나 내용 찾기
		Elements titles = doc.getElementsByTag("title");
		System.out.println(titles);
		System.out.println();
		
		// 타이틀 내용 보기
		System.out.println(titles.text());
		System.out.println();
		
		// 여러개의 타이틀이 있다면
		Elements pTags = doc.getElementsByTag("p");
		System.out.println(pTags);
        System.out.println();
        
		for(int i=0; i<pTags.size(); i++) {
			Element pTag = pTags.get(i);
			System.out.println(pTag);
			System.out.println();
			
			System.out.println(pTag.tagName());
			System.out.println();
			
			System.out.println(pTag.text());
		}
	}

}



태그에 id, class 값으로 특정 태그의 텍스트나 정보 가져오기

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

public class JsoupEx02 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		String html = "<html>"
				+ "<head><title>First parse</title></head>"
				+ "<body>"
				+ "<p id='i1' class='c1'>Parsed HTML into a doc 1.</p>"
				+ "<p id='i2' class='c2'>Parsed HTML into a doc 2.</p>"
				+ "<p id='i3' class='c1'>Parsed HTML into a doc 3.</p>"
				+ "<p id='i4' class='c2'>Parsed HTML into a doc 4.</p>"
				+ "</body>"
				+ "</html>";
		 
		// DOM 객체로 만들기 / Tree처럼 됨
		Document doc = Jsoup.parse(html);
		
		// id 값으로 원하는쪽으로 접근하기
		Element pTag = doc.getElementById("i1");
		System.out.println(pTag.text());
		System.out.println();
		
		// 클래스를 통하여 가지고오기
		Elements pTags = doc.getElementsByClass("c1");
		for(Element e : pTags) {
			// c1클래스이름의 텍스트 가져오기
			System.out.println(e.text());
		}
		
	}

}



CSS / 셀렉터 이용하기, 쓰는방법

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

public class JsoupEx03 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		String html = "<html>"
				+ "<head><title>First parse</title></head>"
				+ "<body>"
				
				+ "<a href='https://www.daum.net'>"
				+ "<img class='c2' src='./daum.jpg'/>"
				+ "<div id='i1'>다음 바로가기</div>"
				+ "</a>"
				
				+ "<a href='https://www.naver.com'>"
				+ "<img class='c1' src='./naver.jpg'/>"
				+ "<div id='i1'>네이버 바로가기</div>"
				+ "</a>"
				
				+ "<a href='https://www.google.com'>"
				+ "<img class='c1' src='./google.jpg'/>"
				+ "<div id='i1'>구글 바로가기</div>"
				+ "</a>"
				
				+ "</body>"
				+ "</html>";
		 
		// DOM 객체로 만들기 / Tree처럼 됨
		Document doc = Jsoup.parse(html);
		
		// CSS 사용기법, 쓰는방법 / select하면 ()에 CSS기법 사용가능
		Elements divTags = doc.select("#i1");
		System.out.println(divTags);
		System.out.println();
		
		// 텍스트 내용만
		System.out.println(divTags.text());
		System.out.println();
		
		// c1클래스들 출력
		Elements imgTags = doc.select("img.c1");
		System.out.println(imgTags);
		System.out.println();
		
		for(Element e : imgTags) {
			// 속성 읽기
			System.out.println(e.attr("src"));
		}
		System.out.println();
		
		// img의 속성의 src의 jpg속성으로 끝나는 것
		Elements imgTags2 = doc.select("img[src$=jpg]");
		System.out.println(imgTags2);
	}

}



문제 - 실시간 뉴스 보는 프로그램

import java.awt.EventQueue;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import javax.swing.JButton;
import java.awt.GridLayout;
import javax.swing.JTextField;
import java.awt.Rectangle;
import java.awt.Component;
import javax.swing.border.TitledBorder;
import javax.swing.border.EtchedBorder;
import java.awt.Color;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

public class News extends JFrame {

	private JPanel contentPane;
	private JTextField textField1;
	private JTextField textField2;
	private JTextField textField3;
	private JTextField textField4;
	private JTextField textField5;
	private JTextField textField6;
	private JTextField textField7;
	private JTextField textField8;
	private JTextField textField9;
	private JTextField textField10;
	private JButton btn1;
	private JButton btn2;
	private JButton btn3;
	private JButton btn4;
	private JButton btn5;
	private JButton btn6;
	private JButton btn7;
	private JButton btn8;
	private JButton btn9;
	private JButton btn10;
	private JPanel panel;

	/**
	 * Launch the application.
	 */
	public static void main(String[] args) {
		EventQueue.invokeLater(new Runnable() {
			public void run() {
				try {
					News frame = new News();
					frame.setVisible(true);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
	}

	/**
	 * Create the frame.
	 */
	public News() {
		setResizable(false);
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setBounds(100, 100, 800, 600);
		contentPane = new JPanel();
		contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));

		setContentPane(contentPane);
		contentPane.setLayout(null);
		
		JButton btn = new JButton("실시간 뉴스보기");
		btn.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent e) {
			}
		});
		btn.setBounds(12, 10, 760, 23);
		contentPane.add(btn);
		
		panel = new JPanel();
		panel.setBorder(new TitledBorder(new EtchedBorder(EtchedBorder.LOWERED, new Color(255, 255, 255), new Color(160, 160, 160)), "\uB274\uC2A4 \uBCF4\uAE30", TitledBorder.LEADING, TitledBorder.TOP, null, new Color(0, 0, 0)));
		panel.setBounds(6, 50, 772, 496);
		contentPane.add(panel);
		panel.setLayout(null);
		
		textField1 = new JTextField();
		textField1.setText("뉴스 내용");
		textField1.setBounds(6, 23, 606, 21);
		panel.add(textField1);
		textField1.setAlignmentX(Component.LEFT_ALIGNMENT);
		textField1.setColumns(10);
		
		textField2 = new JTextField();
		textField2.setText("뉴스 내용");
		textField2.setBounds(6, 73, 606, 21);
		panel.add(textField2);
		textField2.setAlignmentX(Component.LEFT_ALIGNMENT);
		textField2.setColumns(10);
		
		textField3 = new JTextField();
		textField3.setText("뉴스 내용");
		textField3.setBounds(6, 123, 606, 21);
		panel.add(textField3);
		textField3.setAlignmentX(Component.LEFT_ALIGNMENT);
		textField3.setColumns(10);
		
		textField4 = new JTextField();
		textField4.setText("뉴스 내용");
		textField4.setBounds(6, 173, 606, 21);
		panel.add(textField4);
		textField4.setAlignmentX(Component.LEFT_ALIGNMENT);
		textField4.setColumns(10);
		
		textField5 = new JTextField();
		textField5.setText("뉴스 내용");
		textField5.setBounds(6, 223, 606, 21);
		panel.add(textField5);
		textField5.setAlignmentX(Component.LEFT_ALIGNMENT);
		textField5.setColumns(10);
		
		textField6 = new JTextField();
		textField6.setText("뉴스 내용");
		textField6.setBounds(6, 273, 606, 21);
		panel.add(textField6);
		textField6.setAlignmentX(Component.LEFT_ALIGNMENT);
		textField6.setColumns(10);
		
		textField7 = new JTextField();
		textField7.setText("뉴스 내용");
		textField7.setBounds(6, 323, 606, 21);
		panel.add(textField7);
		textField7.setAlignmentX(Component.LEFT_ALIGNMENT);
		textField7.setColumns(10);
		
		textField8 = new JTextField();
		textField8.setText("뉴스 내용");
		textField8.setBounds(6, 373, 606, 21);
		panel.add(textField8);
		textField8.setAlignmentX(Component.LEFT_ALIGNMENT);
		textField8.setColumns(10);
		
		textField9 = new JTextField();
		textField9.setText("뉴스 내용");
		textField9.setBounds(6, 423, 606, 21);
		panel.add(textField9);
		textField9.setAlignmentX(Component.LEFT_ALIGNMENT);
		textField9.setColumns(10);
		
		textField10 = new JTextField();
		textField10.setText("뉴스 내용");
		textField10.setBounds(6, 468, 606, 21);
		panel.add(textField10);
		textField10.setAlignmentX(Component.LEFT_ALIGNMENT);
		textField10.setColumns(10);
		
		btn1 = new JButton("바로가기");
		btn1.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent e) {
			}
		});
		btn1.setBounds(624, 23, 142, 23);
		panel.add(btn1);
		
		btn2 = new JButton("바로가기");
		btn2.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent e) {
			}
		});
		btn2.setBounds(624, 73, 142, 23);
		panel.add(btn2);
		
		btn3 = new JButton("바로가기");
		btn3.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent e) {
			}
		});
		btn3.setBounds(624, 123, 142, 23);
		panel.add(btn3);
		
		btn4 = new JButton("바로가기");
		btn4.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent e) {
			}
		});
		btn4.setBounds(624, 173, 142, 23);
		panel.add(btn4);
		
		btn5 = new JButton("바로가기");
		btn5.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent e) {
			}
		});
		btn5.setBounds(624, 223, 142, 23);
		panel.add(btn5);
		
		btn6 = new JButton("바로가기");
		btn6.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent e) {
			}
		});
		btn6.setBounds(624, 273, 142, 23);
		panel.add(btn6);
		
		btn7 = new JButton("바로가기");
		btn7.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent e) {
			}
		});
		btn7.setBounds(624, 323, 142, 23);
		panel.add(btn7);
		
		btn8 = new JButton("바로가기");
		btn8.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent e) {
			}
		});
		btn8.setBounds(624, 373, 142, 23);
		panel.add(btn8);
		
		btn9 = new JButton("바로가기");
		btn9.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent e) {
			}
		});
		btn9.setBounds(624, 423, 142, 23);
		panel.add(btn9);
		
		btn10 = new JButton("바로가기");
		btn10.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent e) {
			}
		});
		btn10.setBounds(624, 473, 142, 23);
		panel.add(btn10);
	}
}

예시

import java.awt.Color;
import java.awt.EventQueue;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.border.EmptyBorder;
import javax.swing.border.EtchedBorder;
import javax.swing.border.TitledBorder;

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

public class NewsReaderUI02 extends JFrame {

	private JPanel contentPane;
	private JTextField tf01;
	private JTextField tf02;
	private JTextField tf03;
	private JTextField tf04;
	private JTextField tf05;
	private JTextField tf06;
	private JTextField tf07;
	private JTextField tf08;
	private JTextField tf09;
	private JTextField tf10;

	/**
	 * Launch the application.
	 */
	public static void main(String[] args) {
		EventQueue.invokeLater(new Runnable() {
			public void run() {
				try {
					NewsReaderUI02 frame = new NewsReaderUI02();
					frame.setVisible(true);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
	}

	/**
	 * Create the frame.
	 */
	public NewsReaderUI02() {
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setBounds(100, 100, 600, 441);
		contentPane = new JPanel();
		contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
		setContentPane(contentPane);
		contentPane.setLayout(null);
		
		JButton btn00 = new JButton("실시간 뉴스보기");
		btn00.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent e) {
				StringBuilder sbHtml = new StringBuilder();
				
				BufferedReader br = null;
				
				try {
					URLConnection conn = new URL( "https://news.daum.net/" ).openConnection();
					br = new BufferedReader( new InputStreamReader( conn.getInputStream() ) );
					
					String line = null;
					while( ( line = br.readLine() ) != null ) {
						sbHtml.append( line + System.lineSeparator() );
					}
					
					Document doc = Jsoup.parse( sbHtml.toString() );
					
					Elements datas = doc.select( "strong > a[data-tiara-layer='article_main']" );
					
					tf01.setText( datas.get(0).text() );
					tf02.setText( datas.get(1).text() );
					tf03.setText( datas.get(2).text() );
					tf04.setText( datas.get(3).text() );
					tf05.setText( datas.get(4).text() );
					tf06.setText( datas.get(5).text() );
					tf07.setText( datas.get(6).text() );
					tf08.setText( datas.get(7).text() );
					tf09.setText( datas.get(8).text() );
					tf10.setText( datas.get(9).text() );
					
				} catch (MalformedURLException e1) {
					// TODO Auto-generated catch block
					System.out.println( "[에러] " + e1.getMessage() );
				} catch (IOException e1) {
					// TODO Auto-generated catch block
					System.out.println( "[에러] " + e1.getMessage() );
				} finally {
					if( br != null ) try { br.close(); } catch( IOException e1 ) {} 
				}				
			}
		});
		btn00.setBounds(12, 10, 560, 23);
		contentPane.add(btn00);
		
		JPanel panel = new JPanel();
		panel.setBorder(new TitledBorder(new EtchedBorder(EtchedBorder.LOWERED, new Color(255, 255, 255), new Color(160, 160, 160)), "\uB274\uC2A4 \uBCF4\uAE30", TitledBorder.LEADING, TitledBorder.TOP, null, new Color(0, 0, 0)));
		panel.setBounds(6, 45, 566, 350);
		contentPane.add(panel);
		panel.setLayout(null);
		
		tf01 = new JTextField();
		tf01.setEditable(false);
		tf01.setBounds(12, 25, 404, 21);
		panel.add(tf01);
		tf01.setText("뉴스내용");
		tf01.setColumns(10);
		
		JButton btn01 = new JButton("바로가기");
		btn01.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent e) {
			}
		});
		btn01.setBounds(428, 24, 126, 23);
		panel.add(btn01);
		
		tf02 = new JTextField();
		tf02.setEditable(false);
		tf02.setBounds(12, 57, 404, 21);
		panel.add(tf02);
		tf02.setText("뉴스내용");
		tf02.setColumns(10);
		
		JButton btn02 = new JButton("바로가기");
		btn02.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent e) {
			}
		});
		btn02.setBounds(428, 56, 126, 23);
		panel.add(btn02);
		
		tf03 = new JTextField();
		tf03.setEditable(false);
		tf03.setBounds(12, 89, 404, 21);
		panel.add(tf03);
		tf03.setText("뉴스내용");
		tf03.setColumns(10);
		
		JButton btn03 = new JButton("바로가기");
		btn03.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent e) {
			}
		});
		btn03.setBounds(428, 88, 126, 23);
		panel.add(btn03);
		
		tf04 = new JTextField();
		tf04.setEditable(false);
		tf04.setBounds(12, 121, 404, 21);
		panel.add(tf04);
		tf04.setText("뉴스내용");
		tf04.setColumns(10);
		
		JButton btn04 = new JButton("바로가기");
		btn04.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent e) {
			}
		});
		btn04.setBounds(428, 120, 126, 23);
		panel.add(btn04);
		
		tf05 = new JTextField();
		tf05.setEditable(false);
		tf05.setBounds(12, 153, 404, 21);
		panel.add(tf05);
		tf05.setText("뉴스내용");
		tf05.setColumns(10);
		
		JButton btn05 = new JButton("바로가기");
		btn05.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent e) {
			}
		});
		btn05.setBounds(428, 152, 126, 23);
		panel.add(btn05);
		
		tf06 = new JTextField();
		tf06.setEditable(false);
		tf06.setBounds(12, 185, 404, 21);
		panel.add(tf06);
		tf06.setText("뉴스내용");
		tf06.setColumns(10);
		
		JButton btn06 = new JButton("바로가기");
		btn06.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent e) {
			}
		});
		btn06.setBounds(428, 184, 126, 23);
		panel.add(btn06);
		
		tf07 = new JTextField();
		tf07.setEditable(false);
		tf07.setBounds(12, 217, 404, 21);
		panel.add(tf07);
		tf07.setText("뉴스내용");
		tf07.setColumns(10);
		
		JButton btn07 = new JButton("바로가기");
		btn07.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent e) {
			}
		});
		btn07.setBounds(428, 216, 126, 23);
		panel.add(btn07);
		
		tf08 = new JTextField();
		tf08.setEditable(false);
		tf08.setBounds(12, 249, 404, 21);
		panel.add(tf08);
		tf08.setText("뉴스내용");
		tf08.setColumns(10);
		
		JButton btn08 = new JButton("바로가기");
		btn08.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent e) {
			}
		});
		btn08.setBounds(428, 248, 126, 23);
		panel.add(btn08);
		
		tf09 = new JTextField();
		tf09.setEditable(false);
		tf09.setBounds(12, 281, 404, 21);
		panel.add(tf09);
		tf09.setText("뉴스내용");
		tf09.setColumns(10);
		
		JButton btn09 = new JButton("바로가기");
		btn09.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent e) {
			}
		});
		btn09.setBounds(428, 280, 126, 23);
		panel.add(btn09);
		
		tf10 = new JTextField();
		tf10.setEditable(false);
		tf10.setBounds(12, 313, 404, 21);
		panel.add(tf10);
		tf10.setText("뉴스내용");
		tf10.setColumns(10);
		
		JButton btn10 = new JButton("바로가기");
		btn10.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent e) {
			}
		});
		btn10.setBounds(428, 312, 126, 23);
		panel.add(btn10);
	}
}
profile
개발자 꿈나무

0개의 댓글