My Blog List

Monday, January 4, 2016

카카오톡 메세지중 url의 상세정보 처리

카톡을 하면서 url을 보내보았는데 아래와같이 정보들이 보여지길래 API가 있나보다 생각해서 한참을 찾았는데
못찾았네요. 어떻게 할까 고민하다가 Java로 카톡 url 메세지 내용을 따라 하는 소스를 코딩했어요.

먼저 캡처화면을 찍은거를 보여주면 컨텐츠 내용에 url이 담겨져있는거는 사이트의 내용이 요약되어 보여지네요


검색해야하는 내용
1. 이미지가 보여진다
2. 해당 사이트의 Detail이 보여진다.
끝??? 생각보다 분석할 부분이 없네요. ㅡ.ㅡ;


그러면 이미지는 어디에서 확인을 해야할까요?? 일단 네이버 홈페이지에 들어가보았습니다
크롬으로 www.naver.com에 들어가 크롬 개발자모드로 디버깅을 해본결과 meta태그에 내용이 있었습니다.


여기서 meta tag에  property 에 image 와, description을 발견할수 있는데
어떤싸이트에는 og:image 이런식으로 표현하고 또 다른 특정사이트에는 og를 제외한 image라고 표시하던데 둘중에 하나라도 있으면 해당 정보들이 있다고 판단하면 될 것 같네요.


content-type체크 
모든 URL의 반환타입이 html이 아니다. 경우에 따라서 xml을 반환할때도 있고, 특정 파일들을 반환할때도 있는데
어떻게 이 url이 사이트라고 판단을 하냐면 request의 response 값에 content-type을 확인해보면 된다.

json 같은 경우는
application/json 의 형식이고
html같은경우는
text/html 이런식으로 반환해주는데

content-type 규약 사이트에 들어가면 더 자세하게 나와있을것 같네요.


실제 코딩을 해보자. 
1. HttpURLConnection 을 이용하여 url 호출 
2. responseCode == 200(성공) 이고 content-type 이 text/html 일때 전체 html을 파싱준비
3. html 파싱 라이브러리를 사용하지 않고 정규식을 이용해서 meta 태그를 찾고 content 와 property 값이 있는 경우에만 매칭
4. 결과물 출력

사용한 정규식
<meta.*?((content=['\"].*['\"])|(property=['\"].*['\"])).*?((content=['\"].*['\"])|(property=['\"].*['\"])).*?>

해석 : 
<meta 태그로 시작하며
.는 모든 문자를 말하며
*는 0번또는 여러번을 말한다.
content 가 먼저 나올수도 있고 property가 먼저 나올수도 있어서
((content=['\"].*['\"])|(property=['\"].*['\"]))
그룹함수로 그룹을 묶어주었고 | or 표시로 둘중에 하나만 매칭이 되도 매치가 될수 있도록 지정
['\"] 란 홑따옴표가 나올수가 있고 쌍따옴표가 나올수가 있는데 둘중 하나라도 매칭이 되면 OK
.*?다른 변수들이 나올수도 있어서 조건을 넣어주었고
((content=['\"].*['\"])|(property=['\"].*['\"]))
다시 content나 property가 매칭이 되도록 조건을 한번더
>
그리고 마무리는 닫는 태그로.

좋은 방법인지는 모르겠지만 한방에 체크하고 싶어서 복잡한 정규식을 사용했습니다.


그룹함수에 번호를 사용을했는데
((A)|(B)) ((C)|(D))
순서를 매기자면
((A)|(B)) 의값이 1번
(A)의 값이 2번
(B)의 값이 3번
((C)|(D))의 값이 4번
(C)의 값이 5번
(D)의 값이 6번으로 데이터를 캐치할수 있다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
package kakaotalk;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Main {
    public static void main(String args[]){
        URL url;7
        InputStream is = null;
        BufferedReader br;
        String line;
        try {
            url = new URL("http://www.naver.com");
            HttpURLConnection connection = (HttpURLConnection)url.openConnection();
            connection.connect();
            String contentType = connection.getContentType();
            System.out.println(contentType);
            
            int responseCode = connection.getResponseCode();
            System.out.println(responseCode);
            
            if(responseCode== 200){ // 성공
                if(contentType != null ){
                    if(contentType .contains("text/html")){
                        // 파싱 시작
                        br = new BufferedReader(new InputStreamReader(connection.getInputStream(), "UTF-8"));
                        String fullStr = "";
                        StringBuffer bf = new StringBuffer();
                        while ((line = br.readLine()) != null) {
//                            System.out.println(line);
                            
                            bf .append(line).append("\n");
                        }
                        fullStr = bf.toString();
                        
                       // 전체
                       System.out.println(fullStr);
                        
                       long start = System.currentTimeMillis(); 
                       KakaoData data  = getData(fullStr);
                       System.out.println(System.currentTimeMillis()-start);
                    }
                }
            }
            
            
        } catch (MalformedURLException mue) {
             mue.printStackTrace();
        } catch (IOException ioe) {
             ioe.printStackTrace();
        } finally {
            try {
                if (is != null) is.close();
            } catch (IOException ioe) {
                // nothing to see here
            }
        }
    }
    
    class KakaoData {
        public String imagePath =null;
        public String content = null
    }
    
    /**
     * 메타 tag에서 content와 property 값을 가진 라인을 찾는다
     * @param str
     * @return
     */
    public static KakaoData getData(String str) {
        
        String reg = "<meta.*?((content=['\"].*['\"])|(property=['\"].*['\"])).*?((content=['\"].*['\"])|(property=['\"].*['\"])).*?>";
        
        Pattern pattern2 = Pattern.compile(reg,
                Pattern.CASE_INSENSITIVE);
        Matcher matcher2 = pattern2.matcher(str);
        while(matcher2.find()){
            String match2 = matcher2.group();
            System.out.println(" 0 : " + matcher2.group(0));
            System.out.println(" 1 : " + matcher2.group(1));
//            System.out.println(" 2 : " + matcher2.group(2));
//            System.out.println(" 3 : " + matcher2.group(3));
            System.out.println(" 4 : " + matcher2.group(4));
//            System.out.println(" 5 : " + matcher2.group(5));
//            System.out.println(" 6 : " + matcher2.group(6));
            System.out.println();
        }
        
        // 한번더 필터링을 거친후 실제 데이터를 입력을 해주어야함
        return null;
    }
}
cs


결과물 
 0 : <meta property="og:title" content="네이버 메인">
 1 : property="og:title"
 4 : content="네이버 메인"

 0 : <meta property="og:url" content="http://www.naver.com/">
 1 : property="og:url"
 4 : content="http://www.naver.com/"

 1 : property="og:image"

 0 : <meta property="og:description" content="네이버 메인에서 다양한 정보와 유용한 컨텐츠를 만나 보세요">
 1 : property="og:description"
 4 : content="네이버 메인에서 다양한 정보와 유용한 컨텐츠를 만나 보세요"


음... 여기서 필요한 내용을 다시 한번 split을 사용하던 파싱을 해서 뽑아내면 되겠네요.

처음 그림으로 돌아가서 
필요한 데이터는 
detail >>  네이버 메인에서 다양한 정보와 유용한 컨텐츠를 만나 보세요
title  >> 네이버 메인

No comments:

Post a Comment