python/크롤링

[파이썬 크롤러] Tweepy를 이용한 트위터 크롤링 [3]

끼발자 2021. 8. 17. 10:48
반응형

성공했다.

이 모든 영광을 파파고에게.

 

이 메일이 왔다면 당신은 트위터API를 사용할 준비가 되었다는 뜻이다.

 

 

 

트위터 개발자포털에 들어가면 위와 같은 화면이 나온다.

 

 

New Project를 누르면 

 

프로젝트 이름을 설정하고,

 

어디에 사용 할 것인지.

 

프로젝트 설명

 

App의 이름.

 

위의 과정들을 모두 마쳤다면,

 

 

당신의 API key, Secret Key, Breaer Token이 생성된다.

이건 본인만 알고있어야한다.

한 번 발급 이후로는 재발급만 가능하니.

 

만약 잃어버렸다면, 프로젝트 > 프로젝트 명 > Keys and tokens 에서 재발급이 가능하다.

재발급시엔 기존에 사용되던 키는 사라진다.

 

키 발급까지 끝났다면, 이제 트위터 크롤링을 위한 첫 스텝을 밟은 셈이다.

 

pip install tweepy

tweepy를 다운받자. 

 

CONSUMER_KEY = '*************************' 
CONSUMER_SECRET = '**************************************************'
ACCESS_TOKEN = '**************************************************'
ACCESS_TOKEN_SECRET = '**************************************************'

이런식으로 키들을 변수로 지정해서 사용한다.

CONSUMER_KEY는 25자, 나머지는 50자이다.

 

import tweepy # version == 3.10.0

auth = tweepy.OAuthHandler(CONSUMER_KEY,CONSUMER_SECRET)
auth.set_access_token(ACCESS_TOKEN,ACCESS_TOKEN_SECRET)
api = tweepy.API(auth,wait_on_rate_limit=True)
# wait_on_rate_limit 많은 요청이 있을 때, 대기시간을 조절해서 중간에 뻗지 않게 도와준다.

 

tweepy는 cursor를 통해서 데이터를 수집한다.

더 많은 정보는 공식 문서를 참고하자

 

https://docs.tweepy.org/en/stable/

 

Tweepy Documentation — tweepy 3.10.0 documentation

© Copyright 2009-2020, Joshua Roesslein Revision 29df541c.

docs.tweepy.org

 

api를 구성하고나면 다음으로 검색할 키워드를 지정해보자.

분명 처음 게시글을 쓸 땐, BTS가 1위였는데 어느샌가 순위가 내려갔다.

각설하고 초지일관 BTS로 트위터를 수집해보자.

구성 방법은 다음과 같다.

cursor = tweepy.Cursor(api.search,
			q = keyword # 'BTS')

 

다음 반복문을 통해서 우리가 원하는 키워드로 검색을 시작해보자.

 

for i in cursor.items():
	print(i._json)
	break

 

키워드가 키워드다보니 우선, 데이터가 어떤 형태로 출력되는지 확인해보자.

 

{'created_at': 'Tue Aug 17 00:52:40 +0000 2021',
 'id': 1427433160955076610,
 'id_str': '1427433160955076610',
 'text': '@Army097l @BTS_twt Dejo mi voto..\n\n I vote #BTS + #BTSARMY + #BTSGMK #DynamiteBTS + #ButterBTS at the #BreakTudoAwards 2021(@BTS_twt)',
 'truncated': False,
 'entities': {'hashtags': [{'text': 'BTS', 'indices': [43, 47]},
   {'text': 'BTSARMY', 'indices': [50, 58]},
   {'text': 'BTSGMK', 'indices': [61, 68]},
   {'text': 'DynamiteBTS', 'indices': [69, 81]},
   {'text': 'ButterBTS', 'indices': [84, 94]},
   {'text': 'BreakTudoAwards', 'indices': [102, 118]}],
  'symbols': [],
  'user_mentions': [{'screen_name': 'Army097l',
    'name': 'Laura ⟭⟬⁷ ᴮᴱ🏖️🇨🇴',
    'id': 1049444995084800000,
    'id_str': '1049444995084800000',
    'indices': [0, 9]},
   {'screen_name': 'BTS_twt',
    'name': '방탄소년단',
    'id': 335141638,
    'id_str': '335141638',
    'indices': [10, 18]},
   {'screen_name': 'BTS_twt',
    'name': '방탄소년단',
    'id': 335141638,
    'id_str': '335141638',
    'indices': [124, 132]}],
  'urls': []},
 'metadata': {'iso_language_code': 'en', 'result_type': 'recent'},
 'source': '<a href="http://twitter.com/download/android" rel="nofollow">Twitter for Android</a>',
 'in_reply_to_status_id': 1427394211775713285,
 'in_reply_to_status_id_str': '1427394211775713285',
 'in_reply_to_user_id': 1049444995084800000,
 'in_reply_to_user_id_str': '1049444995084800000',
 'in_reply_to_screen_name': 'Army097l',
 'user': {'id': 1271622521666887681,
  'id_str': '1271622521666887681',
  'name': '♡︎Crisk➪',
  'screen_name': 'Cristinameal',
  'location': 'BTS',
  'description': 'OT7➪forever   \n ➪ 𝐒𝐭𝐫𝐞𝐚𝐦 𝐚 𝐏𝐓𝐃  🔊\n☘︎my world and my happiness ☘︎\n#방탄소년단\n😭',
  'url': None,
  'entities': {'description': {'urls': []}},
  'protected': False,
  'followers_count': 41,
  'friends_count': 84,
  'listed_count': 0,
  'created_at': 'Sat Jun 13 01:57:02 +0000 2020',
  'favourites_count': 7772,
  'utc_offset': None,
  'time_zone': None,
  'geo_enabled': True,
  'verified': False,
  'statuses_count': 2432,
  'lang': None,
  'contributors_enabled': False,
  'is_translator': False,
  'is_translation_enabled': False,
  'profile_background_color': 'F5F8FA',
  'profile_background_image_url': None,
  'profile_background_image_url_https': None,
  'profile_background_tile': False,
  'profile_image_url': 'http://pbs.twimg.com/profile_images/1425329480470573056/uUFcYWw9_normal.jpg',
  'profile_image_url_https': 'https://pbs.twimg.com/profile_images/1425329480470573056/uUFcYWw9_normal.jpg',
  'profile_banner_url': 'https://pbs.twimg.com/profile_banners/1271622521666887681/1628659506',
  'profile_link_color': '1DA1F2',
  'profile_sidebar_border_color': 'C0DEED',
  'profile_sidebar_fill_color': 'DDEEF6',
  'profile_text_color': '333333',
  'profile_use_background_image': True,
  'has_extended_profile': False,
  'default_profile': True,
  'default_profile_image': False,
  'following': False,
  'follow_request_sent': False,
  'notifications': False,
  'translator_type': 'none',
  'withheld_in_countries': []},
 'geo': None,
 'coordinates': None,
 'place': None,
 'contributors': None,
 'is_quote_status': False,
 'retweet_count': 0,
 'favorite_count': 0,
 'favorited': False,
 'retweeted': False,
 'lang': 'en'}

 

이것은 ._json 형태로 출력했기 때문에 json형태를 보인다.

json은 dict형태이기 때문에, i._json['text'] 등으로 접근 할 수 있지만,

a.text 를 통해서도 동일한 값을 출력하기 때문에, json은 확인용으로만 사용하면 되겠다.

 

우리는 트위터API를 무료로 사용하고 있고, 무료는 검색시점 일주일 이전까지의 데이터만 가져올 수 있다.

특정일 이전을 검색하고 싶다면, 유료버전을 사용하면 된다.

 

 

검색어에 옵션 주는 방법

 검색어에 옵션은 의외로 간단하다.

트위터에 접속하고, 아무 단어나 검색한 다음, 

 

고급 검색에서 우리가 원하는 기준대로 검색어를 입력해보자.

 

모두 포함 "그대로 포함" (하나 OR 이상 OR 포함) -제외 (#해시태그) (from:작성계정) (to:보내는계정) (@멘션한계정) min_replies:200 min_faves:200 min_retweets:200 lang:ko

 

귀찮을까봐 하나씩 넣어놓고 검색버튼을 눌러보았다.

keyword에 저런 형태로 넣으면 저 상태로 검색이 된다.

keyword = 'BTS "billboard chart" (butter OR HOT) -RT (#army) min_replies:10 min_faves:2 min_retweets:3'

BTS를 포함하고, billboard chart를 그대로 포함하면서 butter or HOT 을 포함, 

리트윗은 제외하고 해시태그는 army 최소 답글은 10개 최소 좋아요는 2개 최소 리트윗은 3개인 트윗을 불러오라는 뜻이다.

 

검색어에 대한 내용은 여기까지 하고,

 

트위터 수집된 데이터를 저장해보도록 하자.

아까 cursor에서 반복문을 통해 불러올 때, 한개만 불러왔다.

반복문을 끝까지 돌면서, 해당 트위터의 텍스트를 저장해보자.

file = open(f'{keyword}.txt','a+',encoding='utf-8') # 위에서 검색으로 정한 키워드
for tweet in cursor.items():
	file.write('Text : {}\nRetweet : {}\nFavorite : {}'\
    .format(tweet.text,tweet.retweet_cout,tweet.favorite_count))
    file.write('-'*180)
file.close()

 

키워드로 명명한 txt 파일에 텍스트와 좋아요 수, 리트윗 수를 담았다. 각각의 트윗들을 -로 구분지었고,

반복문이 끝나면 file.close()로 입력을 종료한다.

 

공식문서를 확인해보면, 자동으로 트윗 올려주는 기능도 있는 것 같다.

필요하다면 참고하길 바란다.

반응형