반응형

# Jsoup API 활용 (Jsoup API 이용한 크롤링(GUI 버전))

  • 년월입 선택하여 특정 사이트에서 데이터 가져와서 보여주기.
  • 응용해서 다양하게 활용할 수 있을것 같다.

  • 작업소스
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;
import org.jsoup.Jsoup;
import org.jsoup.nodes.*;
import org.jsoup.select.Elements;
public class Project02_F extends JFrame implements ActionListener, ItemListener{
	private Choice chyear, chmonth;
	private JLabel yLabel, mLabel;
	private JTextArea area;
	GregorianCalendar gc;
	private int year, month;
	private JLabel[] dayLabel = new JLabel[7];
	private String[] day={"일","월","화","수","목","금","토"};
	private JButton[] days = new JButton[42];	// 7일이 6주이므로 42개의 버튼필요
	private JPanel selectPanel = new JPanel();
	private GridLayout grid = new GridLayout(7, 7, 5, 5);	// 행,열,수평갭,수직갭
	private Calendar ca = Calendar.getInstance();
	private Dimension dimen, dimen1;
	private int xpos, ypos;
	
	public static void main(String[] args) {
		new Project02_F();
	}
	
	public Project02_F(){
		setTitle("웹 페이지 크롤링 GUI : " + ca.get(Calendar.YEAR) + "년" + (ca.get(Calendar.MONTH)+1) + "월" + ca.get(Calendar.DATE) + "일");
		setSize(900,600);
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		
		dimen	= Toolkit.getDefaultToolkit().getScreenSize();
		dimen1	= this.getSize();
		xpos	= (int) (dimen.getWidth()/2 - dimen1.getWidth()/2);
		ypos	= (int) (dimen.getHeight()/2 - dimen1.getHeight()/2);
		
		setLocation(xpos, ypos);	// 화면 가운데 출력.
		setResizable(false);
		setVisible(true);
		
		chyear	= new Choice(); 
		chmonth	= new Choice();
		yLabel	= new JLabel("년"); 
		mLabel	= new JLabel("월");
		
		init();
	}
	
	public void init(){
		select();
		calendar();
	}	
	
	@Override
	public void actionPerformed(ActionEvent arg0) {
		area.setText("");
		String year		= chyear.getSelectedItem();
		String month	= chmonth.getSelectedItem();
		JButton btn		= (JButton) arg0.getSource();
		String day		= btn.getText();
		String bible	= year + "-" + month + "-" + day;
		
		// Jsoup API : HTML파싱
		String url="https://sum.su.or.kr:8888/bible/today/Ajax/Bible/BodyMatter?qt_ty=QT1&Base_de="+bible+"&bibleType=1";
	    
		try {
			Document doc = Jsoup.connect(url).post();

			Element bible_text=doc.select(".bible_text").first();			
			Element bibleinfo_box=doc.select("#bibleinfo_box").first();
			
			// dailybible_info
			Element dailybible_info=doc.select("#dailybible_info").first();
			area.append(dailybible_info.text()+"\n");
			area.append(bible_text.text()+"\n");
			area.append(bibleinfo_box.text()+"\n");
			
			Elements liList=doc.select(".body_list > li");
			
			for (Element  li : liList) {				
				String line=li.select(".info").first().text();
				 
				if (line.length() > 65) {
			 	  line	= line.substring(0,36) 
			 			  + "\n" + line.substring(36,66) 
			 			  + "\n" + line.substring(66) + "\n";	
	 			  area.append(li.select(".num").first().text() + ":" + line);
				} else if (line.length() > 35) {
				  line	= line.substring(0,36) 
						  + "\n" + line.substring(36) + "\n";	
 				  area.append(li.select(".num").first().text() + ":" + line);	
				} else {
				  area.append(li.select(".num").first().text() + ":" + li.select(".info").first().text() + "\n");
				}
			}
		 } catch (Exception e) {
			e.printStackTrace();
		 }		
	}
	
	public void select() {
		JPanel panel = new JPanel(grid);	// 7행 7열의 그리드레이아웃
		
		for (int i = 2022; i >= 2000; i--) {
			chyear.add(String.valueOf(i));
		}
		
		for (int i=1; i <= 12; i++) {
			chmonth.add(String.valueOf(i));
		}
		
		// 레이블에 요일 이름 출력
		for (int i = 0; i < day.length; i++) {
			dayLabel[i] = new JLabel(day[i], JLabel.CENTER);
			panel.add(dayLabel[i]);
		}
		
		dayLabel[6].setForeground(Color.BLUE);	// 토요일 색상
		dayLabel[0].setForeground(Color.RED);	// 일요일 색상
		
		for (int i = 0; i < 42; i++) {	// 버튼 생성 (42개)
			days[i] = new JButton("");	// 제목 없는 버튼 생성
			
			if (i % 7 == 0) {
				days[i].setForeground(Color.RED);	// 일요일 버튼 색
			} else if (i % 7 == 6) {
				days[i].setForeground(Color.BLUE);	// 토요일 버튼 색
			} else {
				days[i].setForeground(Color.BLACK);
			}
			
			days[i].addActionListener(this);
			panel.add(days[i]);
		}
		
		selectPanel.add(chyear);
		selectPanel.add(yLabel);
		selectPanel.add(chmonth);
		selectPanel.add(mLabel);
		
		area=new JTextArea(60, 40);
		area.setCaretPosition(area.getDocument().getLength());
		JScrollPane scrollPane = new JScrollPane(area);  
        
		this.add(selectPanel,	"North");	// 연도와 월을 선택할 수 있는 화면 상단에 출력
		this.add(panel,			"Center");
		this.add(scrollPane,	"East");
		
		String m = (ca.get(Calendar.MONTH) + 1) + "";
		String y = ca.get(Calendar.YEAR) + "";
		
		chyear.select(y);
		chmonth.select(m);
		chyear.addItemListener(this);
		chmonth.addItemListener(this);
	}
	
	public void calendar() {
		year		= Integer.parseInt(chyear.getSelectedItem());
		month		= Integer.parseInt(chmonth.getSelectedItem());
		gc			= new GregorianCalendar(year, month-1, 1);
		int max		= gc.getActualMaximum(gc.DAY_OF_MONTH);	// 해당 달의 최대 일 수
		int week	= gc.get(gc.DAY_OF_WEEK);	//해당 달의 시작 요일

		String today		= Integer.toString(ca.get(Calendar.DATE));	// 오늘 날짜
		String today_month	= Integer.toString(ca.get(Calendar.MONTH) + 1);	// 현재 달

		for (int i = 0; i < days.length; i++) {
			days[i].setEnabled(true);
		}
		
		// 시작일 이전 버튼 비 활성화
		for (int i = 0; i < week-1; i++) {
			days[i].setEnabled(false);
		}
		
		for (int i = week; i < max+week; i++) {
			days[i-1].setText((String.valueOf(i-week+1)));
			days[i-1].setBackground(Color.WHITE);
			
			// 오늘이 속한 달과 같은 달인 경우
			if (today_month.equals(String.valueOf(month))) {
				//버튼의 날짜와 오늘날짜가 일치하는 경우
				if (today.equals(days[i-1].getText())) {
					days[i-1].setBackground(Color.CYAN);	// 버튼의 배경색 지정
				}
			}
		}
		
		// 날짜 없는 버튼 비활성화
		for (int i = (max+week-1); i < days.length; i++) {
			days[i].setEnabled(false);
		}
	}
	
	@Override
	public void itemStateChanged(ItemEvent arg0) {
		Color color = this.getBackground();
		
		if (arg0.getStateChange() == ItemEvent.SELECTED) {
			// 년 or 월 선택 시 기존 달력을 지우고 새로 작성.
			for (int i = 0; i < 42; i++) {
				if (!days[i].getText().equals("")) {
					days[i].setText("");	// 기존 날짜 지움
					days[i].setBackground(color);	// 달력의 배경색과 동일한 색으로 버튼의 배경색 설정
				}
			}
			
			calendar();
		}
	}
}

 

반응형

+ Recent posts