Получение постов и комментариев с Facebook с помощью Python. Часть 1

В предыдущих статьях мы научились получать данные компаний и организаций с их публичных страниц без авторизации. Но так мы могли получить лишь ограниченную информацию: лайки, количество упоминаний и т.п.

В данной серии постов мы переделаем наш скрипт, получающий публичные данные, и узнаем как получать подробные данные о постах и комментариях. В первой части мы рассмотрим как получить данные поста и распечатать их на консоль.

Требования

  • Ознакомление с Граббером публичных данных Часть 1 и Часть 2
  • Python 2.7
  • MySQL 5.6

Регистрация как разработчика приложений Facebook

Прежде чем мы начнем программировать, нам нужно зарегистрироваться в качестве разработчика приложений Facebook. Для этого перейдите по ссылке и, следуя инструкциям, зарегистрируйте свой аккаунт Facebook как разработчика приложений. После того, как вы стали разработчикам приложений Facebook, мы можем создать новое приложение. В верхнем меню выберите Apps -> Create a New App. Заполните форму. Все, что вам нужно, это указать название вашего приложения, выбрать категорию и нажать “Создать приложение”. Я назвал свое приложение “Simple Data Pull”. Вы можете назвать его, как пожелаете.

Создание приложения Facebook

Теперь, когда мы создали приложение Facebook, разверните выпадающий список приложений и выберите “Simple Data Pull” или другое, согласно вашему названию.

На открывшейся странице нас интересуют 2 параметра: App ID и App Secret. Мы будем использовать оба этих параметра далее при авторизации в вызовах Graph API. Не показывайте другим ваши значения App ID и App Secret. Рассматривайте их, как логин и пароль.

App ID и App Secret для приложения

Простая авторизация

В нашем граббере публичных данных мы использовали Graph URL, который меняли и на который обращались для получения JSON объекта, содержащего данные о лайках, упоминаниях и т.п. Для получения JSON объектов постов нам нужно будет изменить этот Graph URL и общаться с сервером по защищенному соединению. Поэтому для начала перейдем к определению переменной graph_url и изменим присваиваемое значение на https://graph.facebook.com/. И хотя это изменение кажется небольшим, оно является необходимым для получения данных по постах по SSL.

def main():
    #to find go to page's FB page, at the end of URL find username
    #e.g. http://facebook.com/walmart, walmart is the username
    list_companies = ["walmart", "cisco", "pepsi", "facebook"]
    graph_url = "https://graph.facebook.com/"

Наши прежние вызовы Graph API, которые мы использовали для получения публичной информации, по прежнему будут работать.

Теперь создадим небольшую функцию, которую будем использовать для преобразования _graph_url__ в URL, с которого мы будем получать данные постов. Над нашей главной функцией создаем функцию с именем create_post_url. Ниже представлен ее код:

def create_post_url(graph_url, APP_ID, APP_SECRET):
    post_args = "/posts/?key=value&access_token=" + APP_ID + "|" + APP_SECRET
    post_url = graph_url + post_args

    return post_url

Давайте рассмотрим эту функцию подробнее. Как вы видите, мы передаем в функцию переменные graph_url, которую мы только что изменили, и две переменные APP_ID и APP_SECRET, полученные нами при создании Facebook приложения. В строке определения post_args формируются дополнительные параметры, необходимые для получения данных постов. Добавление параметров APP_ID и APP_SECRET позволяет Facebook определить, что нам разрешен доступ к данным постов.

В следующей строке мы просто соединяем graph_url с post_args из предыдущей строки и получаем URL с учетными данными, необходимыми для доступа к данным. В конце функции, мы возвращаем полученное значение.

Получение данных постов

Теперь, когда мы создали функцию, которая формирует для нас безопасный URL для получения данных постов, можем применить ее и использовать. Но перед тем, как запускать наш скрипт, давайте посмотрим, какие данные мы будем получать. Для этого сформируем URL для первой итерации цикла. Замените API_ID и API_SECRET на свои значения в адресе:

https://graph.facebook.com/walmart/posts/?key=value&access_token=APP_ID|APP_SECRET

Перейдите по получившемуся адресу и в браузере увидеть следующую картину:

JSON объект данных постов

Подобно тому, как мы рассматривали JSON объект в первой части Граббера Публичных данных Facebook, мы видим тут кучу различной информации. Если вы приглядитесь к данным, которые отображаются в браузере, то заметите, что все они фактически вложены в элемент с ключом “data” JSON объекта. На самом деле в структуре имеются и другие вложения, например для ключей from и properties.

В дальнейших постах мы более детально рассмотрим, как извлечь эти данные. В первой части мы начнем с простого.

Итак, скопируйте приведенный ниже фрагмент кода в главную функцию в ту часть, где выводится page_data на экран.

#extract post data
post_url = create_post_url(current_page, APP_ID, APP_SECRET)
web_response = urllib2.urlopen(post_url)
readable_page = web_response.read()
json_postdata = json.loads(readable_page)
json_fbposts = json_postdata['data']

print json_fbposts

Давайте рассмотрим этот кусок кода. Использую методику из первой части статьи “Граббер публичных данных”, мы открываем соединение на URL и получаем ответ. Замет мы используем метод read() для получение содержимого ответа.

Далее мы преобразуем полученную страницу в JSON объект с именем json_postdata. Содержимое этой переменной представляет собой пары ключ-значение, в том виде, как мы видели в браузере.

Для большего удобства работы с этими данными, мы присваиваем переменной json_fbposts значение элемента JSON объекта с ключом “data”. Теперь, если вы готовы, то можете запустить скрипт. Вы должны увидеть большое количество данных на экране.

Упрощение кода

Поскольку в нашем коде мы несколько раз уже делаем открытие URL и конвертирование ответа, то давайте вынесем это в отдельную функцию, которую сможем вызывать вместо того, чтоб каждый раз писать эти строки кода. Над нашей главной функцией создаем новую с именем render_to_json.

def render_to_json(graph_url):
    #render graph url call to JSON
    web_response = urllib2.urlopen(graph_url)
    readable_page = web_response.read()
    json_data = json.loads(readable_page)

    return json_data

Теперь заменим 4 строки кода в нашей основной функции на вызов render_to_json. Наш код теперь должен быть похож на приведенный ниже. Я понимаю, что это малое изменение, но по мере продвижения далее, это позволит нам сэкономить значительное количество строк кода.

#extract post data
post_url = create_post_url(current_page, APP_ID, APP_SECRET)
json_postdata = render_to_json(post_url)
json_fbposts = json_postdata['data']

print json_fbposts

Хорошо, теперь у нас есть блок данных, которые мы успешно распечатали на экран. Давайте выберем именно те данные, которые нас интересуют. Для начала закомментируем вывод json_fbposts. Далее скопируйте код, представленный ниже, и вставте его ниже того места, где мы распечатывали блок данных постов.

#print json_fbposts

#print post messages and ids
for post in json_fbposts:
    try:
        #try to print out data
        print post["id"]
        print post["message"]

    except Exception:
        print "Error"

В данном блоке кода мы сначала проходим циклом по каждому из постов. Затем для каждого из постов, мы пытаемся получить значения “id” и “message”. Если не получается распечатать эту информацию, то просто выводим общее сообщение об ошибке.

Мы включили блок try/except, т.к. возможны различные ошибки при получении данных из Facebook Graph API. В случае появления таких ошибок мы хотим, чтоб наш скрипт не останавливался, а продолжал работу.

Наш код на текущий момент

В конце первой части “Получения постов и комментариев Facebook” наш код должен выглядеть следующим образом.

import urllib2
import json
import mysql.connector

def connect_db():
    #fill this out with your db connection info
    connection = mysql.connector.connect(user='JohnDoe', password='abc123',
                                         host = '127.0.0.1',
                                         database='facebook_data')
    return connection

def create_post_url(graph_url, APP_ID, APP_SECRET):
    #create authenticated post URL
    post_args = "/posts/?key=value&access_token=" + APP_ID + "|" + APP_SECRET
    post_url = graph_url + post_args

    return post_url

def render_to_json(graph_url):
    #render graph url call to JSON
    web_response = urllib2.urlopen(graph_url)
    readable_page = web_response.read()
    json_data = json.loads(readable_page)

    return json_data


def main():
    #simple data pull App Secret and App ID
    APP_SECRET = "YOUR APP SECRET"
    APP_ID = "YOUR APP ID"

    #to find go to page's FB page, at the end of URL find username
    #e.g. http://facebook.com/walmart, walmart is the username
    list_companies = ["walmart", "cisco", "pepsi", "facebook"]
    graph_url = "https://graph.facebook.com/"

    #create db connection
    connection = connect_db()
    cursor = connection.cursor()

    #SQL statement for adding Facebook page data to database
    insert_info = ("INSERT INTO page_info "
                   "(fb_id, likes, talking_about, username)"
                   "VALUES (%s, %s, %s, %s)")

    for company in list_companies:
        #make graph api url with company username
        current_page = graph_url + company

        #open public page in facebook graph api
        json_fbpage = render_to_json(current_page)

        #gather our page level JSON Data
        page_data = (json_fbpage["id"], json_fbpage["likes"],
                     json_fbpage["talking_about_count"],
                     json_fbpage["username"])
        print page_data

        #extract post data
        post_url = create_post_url(current_page, APP_ID, APP_SECRET)
        json_postdata = render_to_json(post_url)
        json_fbposts = json_postdata['data']

        #print post messages and ids
        for post in json_fbposts:
            try:
                #try to print out data
                print post["id"]
                print post["message"]

            except Exception:
                print "Key error"

            #insert the data we pulled into db
            cursor.execute(insert_info, page_data)

            #commit the data to the db
            connection.commit()
    connection.close()

if __name__ == "__main__":
    main()

Source: Harvesting Facebook Posts and Comments with Python

 
comments powered by Disqus