Java, HTML 코드 분석기 만들기
간단하게 HTML 코드 분석기 프로그램을 만들어 보고자 합니다.
여러가지 기능 중 이미지 다운로드 정도로 하여 진행 해 보도록 하겠습니다.
링크을 통해 jar파일을 다운로드 합니다. https://jsoup.org/
jsoup: Java HTML parser, built for HTML editing, cleaning, scraping, and XSS safety
jsoup: Java HTML Parser jsoup is a Java library that simplifies working with real-world HTML and XML. It offers an easy-to-use API for URL fetching, data parsing, extraction, and manipulation using DOM API methods, CSS, and xpath selectors. jsoup implement
jsoup.org
다음 서비스 클래스 3개와 UI 클래스 1개를 정의 합니다.
URLAnalyzer
HTML의 코드 분석을 담당할 Class 입니다.
두가지의 방식이 있습니다.
1. ULR class를 사용하여 DOM 요소를 가지고 오는 방법은 다음과 같습니다.
public void htmlCodeSearchAnalyzer(String url){
StringBuffer sbuffer = new StringBuffer();
try{
URL reqUrl = new URL(url);
URLConnection urlCon = (URLConnection) reqUrl.openConnection();
InputStreamReader reader = new InputStreamReader(urlCon.getInputStream(), "UTF-8");
BufferedReader buff = new BufferedReader(reader);
String content;
while((content = buff.readLine()) != null){
content = content.replaceAll("\\s", "");
sbuffer.append(content+"\n");
}
buff.close();
setSb(sbuffer);
} catch (Exception e) {
}
}
replaceAll의 정규식 \s은 공백 문자를 찾습니다.
찾은 DOM 요소를 StringBuffer에 append 합니다.
2. Jsoup 라이브러리를 이용하여 DOM 요소를 가지고 오는 방법은 다음과 같습니다.
public void htmlCodeSearchImageTag(String url){
List<String > imgUrlList = new ArrayList<String>();
StringBuffer sbuffer = new StringBuffer();
try{
Document doc = Jsoup.connect(url).get();
Elements newsHeadlines = doc.getAllElements();
for (Element headline : newsHeadlines) {
String imgURL = headline.absUrl("src");
if(!"".equals(imgURL) && imgURL != null){
int ext = imgURL.lastIndexOf(".");
String extName = imgURL.substring(ext+1, imgURL.length());
if("PNG,JPG,JPEG,GIF,TIFF,BMP,".contains(extName.toUpperCase())){
sbuffer.append(imgURL+"\n");
imgUrlList.add(imgURL);
}
}
}
setSb(sbuffer);
setUrlList(imgUrlList);
} catch (Exception e){
}
}
Document doc = Jsoup.connect(url).get();
URL을 get() 요청하여 해당 URL의 DOM 정보를 반환 받습니다.
HTML의 element를 src가 포함되어 있는 url 정보만 체크 합니다.
만약 이미지 파일 이라면 imgUrlList에 add 합니다.
Class 어디서나 사용 할 수 있게 Getter, Setter 메소드를 생성 해 줍니다.
public StringBuffer sb;
public List<String> urlList;
public void setUrlList(List<String> urlList){
this.urlList = urlList;
}
public List<String> getUrlList(){
return this.urlList;
}
public void setSb(StringBuffer sb){
this.sb = sb;
}
public StringBuffer getSb(){
return this.sb;
}
get, set 생성까지 완료 후
URLDownload
HTML 코드 분석 후 이미지 링크(파일)를 추출하여 파일 다운로드를 담당할 Class 입니다.
public void urlFileDownLoad(String paramUrl, List<String> urlList){
try {
String rootPath = System.getProperty("user.home") + "\\imgDownload";
File dir = new File(rootPath);
if(!dir.exists()){
dir.mkdir();
}
for(int i = 0; i < urlList.size(); i++){
URL url = new URL(urlList.get(i));
ReadableByteChannel rbc = Channels.newChannel(url.openStream());
int ext = urlList.get(i).lastIndexOf(".");
String extName =urlList.get(i).substring(ext, urlList.get(i).length());
FileOutputStream fos = new FileOutputStream(rootPath+"\\"+i+extName);
fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE);
fos.close();
}
} catch (Exception e){
}
}
window user 폴더에 imgDownload 폴더가 있는지 체크 후 없으면 폴더를 생성하고, 해당 URL을 호출 합니다.
그리고 해당 다운로드 할 파일의 확장자에 맞게 파일을 다운로드 합니다.
마지막 문자열의 "." 구하고, 전체 문자열의 길이를 subString하여 다운로드 받을 확장자에 맞게 저장 합니다.
StringUtil
여러 문자열 체크 및 생성에 도구를 만들 Class 입니다.
코드는 다음과 같습니다.
private static final String URL_REGEX =
"^((((https?|ftps?|gopher|telnet|nntp)://)|(mailto:|news:))"
+ "(%[0-9A-Fa-f]{2}|[-()_.!~*';/?:@&=+$,A-Za-z0-9])+)"
+ "([).!';/?:,][[:blank:]])?$";
public static boolean urlCheck(String url){
Matcher matcher = Pattern.compile(URL_REGEX).matcher(url);
return matcher.matches();
}
정규식 표현 URL_REGEX 변수를 통해
urlCheck(String url) 메소드 호출 시
요청한 URL이 올바른 URL인지 체크하여 true / false를 반환 합니다.
UI 클래스의 경우
따로 UI가 없어, Java JFrame을 이용하여 처리하면 다음과 같습니다.
JFrame를 표현 할 클래스는 싱글톤으로 구현 합니다. JFrame 인스턴스를 여러개를 생성 할 필요가 없습니다.
( Java SingleTon pattern(자바 싱글톤 패턴) 구현 및 설명 : https://devdalbi.tistory.com/36 )
private static UserInterface jFrame;
private UserInterface(){
createUI();
}
public static UserInterface start(){
if(jFrame == null){
synchronized (UserInterface.class){
jFrame = new UserInterface();
}
}
return jFrame;
}
UserInterface class에서 JFrame을 상속(extends)받아 처리합니다.
그리고 생성자를 호출 할 때 UI를 구성하는 메소드를 호출 해 줍니다.
UserInterface class를 호출하면 시스템이 로딩 될 것입니다.
Main method는 다음과 같습니다.
public class Main {
public static void main(String[] args) {
UserInterface.start();
}
}
UI 작업에 필요한 변수를 선언합니다.
// 입력 및 확인
private JTextField jtInput;
private JTextArea jtArea;
// 버튼
private JButton jbSearch = new JButton("검색");
private JButton jbshutDown = new JButton("종료");
private JButton jbImageCheck = new JButton("이미지 태그 분석");
private JButton jbImageDownLoad = new JButton("이미지 다운로드");
private JButton jbCondition = new JButton("기능 공사중");
private JButton jbVersion = new JButton("안내");
// 스크롤
private JScrollPane jScrollPane;
createUI() method는 다음과 같습니다.
레이아웃의 경우 사용자 지정으로 처리하였습니다.
private void createUI(){
setSize(505, 850);
setLocation(700, 300);
setTitle("URL HTML 분석기 제작자: Dalbi / 달비의 IT 기술 연구");
setLayout(null);
JLabel jLable = new JLabel("URL을 입력하세요");
JLabel jLableLog = new JLabel("분석된 태그");
ImageIcon icon = new ImageIcon("image/URLIamge.png");
JLabel jImgLable = new JLabel("", JLabel.CENTER);
jtArea = new JTextArea();
jtInput = new JTextField();
jScrollPane = new JScrollPane(jtArea);
jScrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED);
jScrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
jImgLable.setIcon(icon);
// 보고 입력
//jtArea.setBounds(5, 200, 463, 400);
jtArea.setEditable(false);
// 스크롤
jScrollPane.setBounds(5, 200, 480, 400);
jtInput.setBounds(5, 625, 350, 35);
// 라벨
jLable.setBounds(5, 605, 100, 20);
jLableLog.setBounds(5, 180, 100, 20);
jImgLable.setBounds(5, 0, 490, 200);
// 버튼 리스트
jbSearch.setBounds(360, 625,60, 35);
jbshutDown.setBounds(425, 625,60, 35);
jbImageCheck.setBounds(5, 670, 130, 130);
jbImageDownLoad.setBounds(145, 670, 130, 130);
jbCondition.setBounds(285, 670, 130, 130);
jbVersion.setBounds(425, 670, 60, 130);
// 버튼 이벤트 맵핑
List<JButton> btnList = new ArrayList<JButton>();
btnList.add(jbSearch);
btnList.add(jbshutDown);
btnList.add(jbImageCheck);
btnList.add(jbImageDownLoad);
btnList.add(jbCondition);
btnList.add(jbVersion);
btnEventMapping(btnList);
add(jImgLable);
add(jLable);
add(jLableLog);
//add(jtArea);
add(jScrollPane);
add(jtInput);
add(jbSearch);
add(jbshutDown);
add(jbImageCheck);
add(jbImageDownLoad);
add(jbCondition);
add(jbVersion);
setVisible(true);
setResizable(false);
setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
}
위 코드의 중간에 보면 버튼을 리스트에 담아
버튼의 이벤트를 mapping시키는 method가 있습니다. 버튼 이벤트 mapping은 다음과 같습니다.
// 버튼 이벤트 mapping
private void btnEventMapping(List<JButton> btnList){
URLAnalyzer analyzer = new URLAnalyzer();
for(int i = 0; i < btnList.size(); i++){
// 동적 이벤트 처리
btnList.get(i).addActionListener(new ActionListener(){
@Override
public void actionPerformed(ActionEvent e) {
Object objCommand = e.getActionCommand();
Object objSource = e.getSource();
String url = jtInput.getText();
if(objSource == jbSearch){
if(StringUtil.urlCheck(url)){
analyzer.htmlCodeSearchAnalyzer(url);
jtArea.setText(analyzer.getSb().toString());
} else {
JOptionPane.showMessageDialog(null, "유효하지 않은 URL 입니다.", "알림", JOptionPane.PLAIN_MESSAGE);
return;
}
} else if(objSource == jbshutDown){
System.exit(0);
} else if(objSource == jbImageCheck){
analyzer.htmlCodeSearchImageTag(url);
if(analyzer.getSb() == null){
JOptionPane.showMessageDialog(null, "검색된 이미지가 없습니다.", "알림", JOptionPane.PLAIN_MESSAGE);
return;
}
jtArea.setText(analyzer.getSb().toString());
} else if(objSource == jbImageDownLoad){
analyzer.htmlCodeSearchImageTag(url);
if(analyzer.getSb() == null){
JOptionPane.showMessageDialog(null, "다운로드 할 이미지가 없습니다.", "알림", JOptionPane.PLAIN_MESSAGE);
return;
}
jtArea.setText(analyzer.getSb().toString());
URLDownload urlDownload = new URLDownload();
urlDownload.urlFileDownLoad(analyzer.getSb().toString(), analyzer.getUrlList());
} else if(objSource == jbCondition){
} else if(objSource == jbVersion){
JOptionPane.showMessageDialog(null, "현재 version 0.1", "알림", JOptionPane.PLAIN_MESSAGE);
return;
}
}
});
}
}
버튼 Object에 따라 해당 Mapping된 event를 호출 합니다.
결과는 다음과 같습니다.

기본적은 폼은 위 사진과 같습니다.
URL Class를 이용한 방법 검색 버튼 클릭 후 테스트

이미지 태그 분석 버튼 클릭 해당 URL에서 이미지 다운로드 테스트

이미지 다운로드 시

정상적으로 이상없이 다운로드 됩니다 !
경로: C:\Users\userName\imgDownload
jar를 빌드하여, exe 파일로 변경하였습니다. ( 상단 사진이 노출되지 않을 수 있습니다. )
시스템 파일은 다운로드 할 수 있게 올리겠습니다. ( app의 기관 등록 및 정보를 입력하지 않았기 때문에, 사용시 바이러스 오진 할 수 있습니다. 바이러스 없습니다 !! )

'Back-End > Java' 카테고리의 다른 글
| Java, Apache PDFBox를 이용하여 PDF 다루기 (0) | 2024.05.14 |
|---|---|
| Java Excel(엑셀) 데이터 처리하기(Apache POI), Excel(엑셀) 다운로드, Excel 생성 (0) | 2024.05.14 |
| Java SingleTon pattern(자바 싱글톤 패턴) 구현 및 설명 (0) | 2024.05.14 |
| Java Xstream xml API 사용 중, ClassCastException 오류(Xstream, Classloader, Thread, Reflection, JVM) (0) | 2024.05.14 |
| Spring, Java 웹 사이트 세션(Session) 관리하기(웹 사이트 로그인 기능, 웹 사이트 session, 웹 로그인 처리) (0) | 2024.05.14 |