본문 바로가기

Infomation

트위터(twitter) API로 데이터 수집 01

https://kmongcom.wordpress.com/2014/03/28/%ED%8A%B8%EC%9C%84%ED%84%B0twitter-api%EB%A1%9C-%EB%8D%B0%EC%9D%B4%ED%84%B0-%EC%88%98%EC%A7%91%ED%95%98%EA%B8%B0/

트위터(twitter) API로 데이터 수집하기

이 글은 크몽 재능인, socurites님이 원고를 기고하셨습니다.

트위터 데이터를 수집하려면 돈을 내야하지만, 학습 및 테스트를 위한 목적이라면 샘플링 방식으로 데이터 중 일부를 수집할 수 있다.

개요

트위터에서는 2 종류의 API를 제공한다.

  • REST API
  • 스트리밍(Streaming) API

여기에서는 스트리밍 API를 사용하겠다. 스트리밍 API에는 3가지 종류의 수집 방식이 있다.

  • 공개 스트림(Public steam)
    트위터에 공개된 데이터 스트림으로, 특정 사용자나 특정 주제와 관련된 데이터를 수집하여 데이터 마이닝하기에 적합
  • 사용자 스트림(User stream)
    한명의 특정 사용자와 관련된 거의 모든 데이터 스트림
  • 사이트 스트림(Site stream)
    다수의 사용자를 대신해서 트위터에 접속한 서버를 위한 데이터 스트림

여기에서는 특정 단어를 포함하는 트위터를 수집하려고 하며, 이 목적에는 공개 스트림이 적합하다. 공개 스트림에는 또한 3가지 방식이 존재한다.

  • POST status/filter
    지정한 필터링 조건에 맞는 공개 트윗만을 수집
  • GET status/sample
    공개 스트림 중 일부를 샘플링
  • GET status/firehose
    모든 공개 스트림을 수집

특정 단어를 포함하는 트윗을 수집하는 목적에는 POST status/filter가 가장 적합하다.

OAuth 계정 acccess token 생성하기

트윗을 수집하려면 OAuth 계정에 대한 access token을 생성해야 한다. 먼저 twitter application을 생성한 후, 관련된 인증 정보를 받을 수 있다.

트위터 수집기 만들기

먼저 앞서 생성한 계정과 관련된 정보를 멤버 변수로 선언한다.

1
2
3
4
5
public class TwitterConsumer extends Thread {
    private final String ACCESS_TOKEN = "자신의 access_token 데이터";
    private final String ACCESS_SECRET = "자신의 access secret 데이터";
    private final String CONSUMER_KEY = "자신의 consumer key 데이터";
    private final String CONSUMER_SECRET = "자신의 consumer secret 데이터";

그리고 트위터를 전송받을 URL을 멤버 변수로 선언한다. 이때 특정 단어만 포함된 트윗만을 수집하려면 해당 필터링 단어는 track 변수에 지정한다. 필터링 단어가 여러개인 경우 콤마(,)로 분리한다.

1
2
3
4
5
6
public class TwitterConsumer extends Thread {
    ....
    // 트위터 스트림을 받을 url 변수를 설정한다.
    // 트위터 스트림 중에서 특정 단어가 들어간 스트림만을 필터링해서 받으려면 track 변수에 지정한다.
    // 두가지 이상의 필터링 단어가 있는 경우, 콤마(,)로 구분하여 쓴다.
    private final String FEED_URL = "https://stream.twitter.com/1.1/statuses/filter.json?track=socurites,football";

이제 트윗을 전송 받는 일은 아래와 같이 간단히 처리할 수 있다.

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
// 접속하기
OAuthConsumer consumer = new CommonsHttpOAuthConsumer(CONSUMER_KEY, CONSUMER_SECRET);
consumer.setTokenWithSecret(ACCESS_TOKEN, ACCESS_SECRET);
// POST status/filter 방식으로 받기 위해 HttpPost 객체를 생성한다.
HttpPost request = new HttpPost(FEED_URL);
consumer.sign(request);
 
// 스트림을 받기 위한 HttpClient 객체를 생성한다.
DefaultHttpClient client = new DefaultHttpClient();
// 필터링 단어를 파라미터로 설정한다.
HttpParams params = new BasicHttpParams();
params.setParameter("track", "socurites,fooball");
request.setParams(params);
 
// 클라이언트 객체를 주어진 요청 객체(request)를 사용해서 실행하여 응답 객체를 생성한다.
HttpResponse response = client.execute(request);
 
// 아래는 응답 스트림을 출력하기 위한 코드
BufferedReader reader = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
 
// 전송받은 데이터 파일에 쓰기
while (true) {
    String line = reader.readLine();
    if (line == null)
        break;
    if (line.length() > 0) {
        if (bytesWritten + line.length() + 1 > BYTES_PER_FILE)
            rotateFile();
        fw.write(line + "\n");
        bytesWritten += line.length() + 1;
        Messages++;
        Bytes += line.length() + 1;
    }
}

코드에서 보는 바와 같이, 접속할 때는 필터링 파라미터가 필요 없으나 트윗을 전송 받을 때는 파라미터를 반드시 지정해야 한다. 사실 잘 모르겠는데..FEED_URL에 지정하면 되는 것 같기도 하고. 현재는 중복해서 지정해두었다.