Краткая инструкция о том, как просто собрать данные из твиттера для своего исследования
© pixabay.com
Рано или поздно, каждый из нас загорается желанием провести собственное лингвистическое исследование. Не важно, что именно является мотивацией и насколько масштабным это исследование должно стать, но желание возникает так или иначе, и немедленно упирается в первую проблему: необходимости протестировать гипотезу на каких-нибудь данных, корпусе.
Разумеется, огромное количество корпусов уже доступны онлайн, начиная с НКРЯ (Национального корпуса русского языка) и заканчивая корпусом ремарок во французском языке семнадцатого века.
Но иногда гораздо удобнее создать корпус под свое исследование самостоятельно: и сейчас я расскажу как это сделать. (Если, конечно, твиты смогут помочь вам в вашем исследовании)
* — Не знаете, что такое IDE? Не проблема! Фактически, это просто некоторая среда, в которой вы можете писать программу, на русский эта аббревиатура переводится не слишком музыкальным сочетанием ИСР — интегрированная среда разработки. Для удобства можете думать о ней как об аналоге LibreOffice или Word — мы, конечно, могли писать все наши тексты в блокноте, но это вряд ли бы было очень удобно, верно?
Одна из самых известных и простых в использовании IDE это PyСharm, который вы легко можете скачать бесплатно: вот здесь. Если вы предпочитаете идти собственным путем, то, пожалуйста, гугл сразу выдает кучу топ-листов с разнообразными IDE на любой вкус 🙂
(Не забудьте поделиться интересными находками!)
Важное уточнение: моей целью здесь было сделать не самый эффективный код для работы, а, скорее, достаточно понятно объяснить как добиться желаемого результата.
Еще одно важное уточнение: Если вы уже умеете кодить и не любите, когда вам объясняют тривиальные детали, просто доскролльте до конца страницы, где я выложила полную версию кода 😉 Сразу хочу заметить, что он просто выполняет свою работу и далек от идеала (моим приоритетом была доступность, а не функциональность), потому, если у вас есть альтернативные решения, или вам интересно посмотреть на более функциональные решения, я очень готова к диалогу!
Нам понадобится API, чтобы иметь возможность взаимодействовать с твиттером. Для того, чтобы получить его, по новым правилам твиттера, нужно запросить разрешение на аккаунт разработчика. Опишите как можно подробнее для чего он вам понадобится (дорогие коллеги подсказывают, что ограничиться отпиской типа “научная работа” не получится).
После того, как просьба будет удовлетворена, щелкните на “создать новое приложение” и заполните форму. После этого самая мучительно-бюрократическая часть позади.
Нам понадобятся API Key и API Secret, а также свеже-сгенерированные Access Token и Access Token Secret.
Сохраните их в отдельный файл (назовите его keys.py) и со свободной душой забудьте про свой твиттер аккаунт.
Переходим к более увлекательной части — начинаем кодить. Сначала возьмемся за файл с ключами. Создаем для них четыре переменные (см. ниже). Лучше не включать файл в полную версию программы, потому что с помощью кодов можно совершать действия от вашего имени.
consumer_key = ""
consumer_secret = ""
access_token = ""
access_secret = "" Тут наступает момент мучительного выбора: нужно решить, какую программную библиотеку использовать для работы с твиттером. Их немало, полный лист можно найти здесь.
Самой популярной библиотекой (пакетом), по ощущениям, является tweepy, и я буду работать именно на ее примере. Но найти документации или туториалы для других библиотек вряд ли будет проблемой.**
Сначала мы создаём файл scrape_twitter.py импортируем необходимые нам библиотеки и файл keys.py, где хранятся ключи доступа:
import keys
import tweepy
import json
import langdetect as ld В первых четырех строках мы вызываем переменные из соседнего файла (оба файла должны являться частью одного проекта).
** — Никогда не устанавливали и не использовали стороннюю библиотеку на Python? Все еще никаких проблем 🙂 Вот здесь довольно подробный туториал как это сделать, если вы раньше никогда этого не делали
consumer_key = keys.consumer_key
consumer_secret = keys.consumer_secret
access_token = keys.access_token
access_secret = keys.access_secret
auth = tweepy.OAuthHandler(consumer_key, consumer_secret)
auth.set_access_token(access_token, access_secret)
api = tweepy.API(auth,
wait_on_rate_limit=True,
wait_on_rate_limit_notify=True) Здесь мы просто слепо следуем любому Tweepy туториалу — и подключаемся к API twitter’a через Tweepy.
Один из моментов, на который мне хочется сейчас обратить внимание это wait_on_rate_limit=True, опциональный элемент. Почему он нам нужен? Фактически, твиттер ограничивает количество запросов, которые вы можете сделать, и требует от вас остановиться на пятнадцать минут, если вы добрались до лимита запросов.
Мы можем протестировать, было ли удачным наше подключение с помощью команды:
print(api.me().name) Она должна напечатать имя вашего аккаунта. Если этого не произошло, значит, что-то пошло не так и самое время почувствовать себя настоящим программистом. А настоящие программисты ищут ответы на StackOverflow, где кто-то наверняка уже решил вашу проблему.
Кстати, если вы впервые слышите о StackOverflow, самое время с ним ознакомиться, это один из главных помощников при программировании наряду с чтением документации.
Скорее всего, если у вас что-то пошло не так, хотя бы у кого-то уже было что-то похожее, а кто-нибудь, может быть, даже нашел решение этой проблемы).
Пришло время еще одного непростого выбора, который, впрочем, должен довольно легко решаться в зависимости от вашей цели: по какому принципу вы хотите отбирать твиты? Вариантов несколько: можно либо выбирать твиты в режиме онлайн с помощью Streaming API, фильтруя с помощью языка, ключевых слов или геолокации, либо искать слова с помощью Search API, выбирая из уже существующего корпуса. (Если вы не привыкли работать с документацией, пример кода с API search можно найти, например, тут. Спасибо, Stack Overflow <3)
У обоих есть свои плюсы и минусы, и про оба написано немало статей. Выбор становится очевидным, когда вы работаете с языком страны, где твиттер не слишком популярен. Например, мои друзья недавно анализировали сербский.
Если такой проблемы возникнуть не должно, то я бы советовала Streaming API, по нему достаточно туториалов, потому, если где-то возникнет ошибка, вам будет проще ее поправить.
Я поставлю для себя такую задачу: хочу найти сто твитов на русском (по возможности, без примеси других языков), используя ключевые слова футбол, собака, песик и ты. Текст твита должен быть длиннее пятидесяти знаков.
Я также хочу собрать определенное количество твитов (предположим, 100). Я также хочу сохранить их в json файл, потому что так мне будет легче в дальнейшем манипулировать данными. (Об манипуляциях мы расскажем в одной из будущих статей).
Я импортирую json и еще одну библиотеку, которая называется langdetect, с ее помощью я смогу еще раз протестировать, написан ли твит на русском.
Это поможет избежать ситуаций, как у моего друга Адама:
Итак, я создаю глобальную переменную с количеством твитов, которые я хочу получить. Число может быть сколь угодно большим (в пределах разумного), но не забывайте, что работа программы занимает некоторое время. Если вы хотите начать работать с данными немедленно, я предлагаю разбивать очень большие числа на средние группы (например, по тысяче штучек).
TOTAL_NUMBER = 100 Дальше мы создаем класс MSL — аббревиатура от MyStreamListener , использующий StreamListener библиотеки Tweepy. (Кажется, названия здесь говорят за себя). Первая функция будет выступать для нас в роли цикла, с помощью ее мы будем повторять наши нехитрые операции снова и снова. Для всех тех, кто не привык к Python, обратите внимание что название функции __init__ имеет значение, и заменить ее на произвольное название не получится.
class MSL(tweepy.StreamListener):
def __init__(self):
super(MSL, self).__init__()
self.counter = 0
self.all_tweets = [] all_tweets я буду использовать для того, чтобы записать в итоге твиты в json файл, а переменная counter поможет мне в подсчетах того, сколько твитов прошло мою двойную проверку, и просигнализирует программе, когда пора остановиться.
#cледующая функция: начинаем с загрузки json'a, которому скармливается информация прошедшая фильтр.
# (Фильтр мы увидим позже)
def on_data(self, data):
data_temp = json.loads(data, encoding='utf-8')
try:
if len(data_temp["text"]) > 50 and ld.detect(data_temp["text"]) == 'ru':
self.all_tweets.append(data_temp)
self.counter += 1
print(data_temp["text"])
print(self.counter)
if self.counter == TOTAL_NUMBER:
#rus.json это название json файла, а "а" здесь значит "append", то есть файлы будут
#обновляться. Впрочем, зная капризный json формат, скорее всего вам придется немного
#подправлять файл мануально после каждого обновления
file = open('rus.json', 'a')
file.write(json.dumps(self.all_tweets, indent=4))
file.close()
return False
except:
pass
return True Теперь давайте рассмотрим try и except. Это довольно непрофессиональный взгляд на проблему: если откуда-то появится ошибка, например, у твита, на который я буду смотреть, не будет поля text, я предлагаю программе просто его проигнорировать и продолжать заниматься своими делами.
Это связано с чисто технической стороной дела: я сохраняю все твиты не по ходу дела, а когда выполнение основного цикла закончится. Соответственно, если программа поймает ошибку, все накопленные мной твиты обратятся в пыль, фигурально выражаясь.
Теперь, немного подробнее о части try: в первом if-statement я рассматриваю атрибут текст моего json файла и проверяю, чтобы он был длиннее 50 знаков, а потом дополнительно удостоверяюсь, что язык и вправду русский.
Дальше я добавляю все это в all_tweets и увеличиваю counter.
Это также хорошее место в программе для того, чтобы проконтролировать себя и задать себе вопрос, чем ты, собственно, занимаешься. Например, можно печатать здесь тексты твитов прошедших проверку: так будет легче проследить что вы получаете именно то, что хотите.
Либо дополнительно установить counter — так вам будет понятно сколько еще ждать до конца программы.
print(data_temp["text"])
print(self.counter) Следующий if-statement проследит за тем, чтобы мы сохранили именно столько твитов сколько нам нужно. Он же откроет json файл и сохранит туда набранные твиты.
Нам остались только три строки кода!
twitter_stream = tweepy.Stream(auth, MSL())
keywords = [u'песик', 'футбол', 'собака', 'ты']
twitter_stream.filter(track=keywords, languages=['ru']) Тут филологическое мышление, должно быть, проведет параллель между сюжетом и фабулой. По факту, конечно, программа сначала прочитает эти строки, которые заставят ее вызвать объект MSL.
В последней строке с фильтром мы еще раз проверяем что язык русский и подтверждаем, какие ключевые слова мы ищем.
Компания Google представила много новых ИИ-продуктов, а модель GPT опровергла известную математическую гипотезу Пала Эрдёша — рассказываем, что произошло в мире ИИ за последнее время
Facebook* и Instagram* будут сканировать фото и видео, чтобы находить детей, которые скрыли свой возраст
Можно ли заниматься NLP, если при словах «производная» и «матрица» хочется закрыть ноутбук? Да — если изучать математику не абстрактно, а через реальные задачи. Объясняем, какие разделы действительно нужны джуну,…