CoderCastrov logo
CoderCastrov
Парсер

Как создать приложение анализа профиля Instagram с использованием Python и Streamlit

Как создать приложение анализа профиля Instagram с использованием Python и Streamlit
просмотров
6 мин чтение
#Парсер

Программирование

Самый простой способ создать приложения на Python


Streamlit - отличная библиотека, которая помогает создавать приложения на Python с минимальными усилиями. Она не только проста в использовании, но и имеет красивый и профессиональный пользовательский интерфейс. Наша идея для этого поста - создать панель управления Instagram, содержащую некоторую описательную статистику о профиле пользователя, такую как наиболее часто используемые хэштеги, самые популярные посты, уровень вовлеченности и т. д. С учетом этого, нам нужно приложение, которое принимает в качестве входных данных имя пользователя и будет парсить его информацию с Instagram для вывода конечной панели управления.

Получение данных из Instagram

Это самая сложная часть, потому что Instagram не любит быть парсингом. К счастью, существует библиотека под названием instagram-scraper, которая является командной строкой на Python, которая парсит профили Instagram без проблем (просто не используйте ее слишком часто).

Установка:

pip install instagram-scraper

Использование:

instagram-scraper "{username}" --profile-metadata  --media-metadata  --media-types none

С помощью указанной выше команды будет создана папка с именем пользователя, содержащая JSON-файл с нашими данными. Имейте в виду, что мы должны запустить код в командной строке.

Давайте запустим пример, используя мой аккаунт Instagram:

instagram-scraper "billybonaros" --profile-metadata  --media-metadata  --media-types none

Мы можем открыть JSON-файл с помощью Python, чтобы увидеть, что у нас есть.

js **=** json.load(open('billybonaros/billybonaros.json', encoding**=**'utf-8'))

js.keys()

dict_keys(['GraphImages', 'GraphProfileInfo'])

В GraphImages содержатся данные о постах, такие как лайки, комментарии и т. д., а GraphProfileInfo содержит информацию о пользователе.

js['GraphProfileInfo']

{'created_time': 1286323200,
 'info': {'biography': 'Artist \nArtificial Intelligence & Data Science\npredictivehacks.com',
  'followers_count': 3486,
  'following_count': 2681,
  'full_name': 'Billy Bonaros',
  'id': '43176775',
  'is_business_account': False,
  'is_joined_recently': False,
  'is_private': False,
  'posts_count': 221,
  'profile_pic_url': 'https://instagram.fath3-3.fna.fbcdn.net/v/t51.2885-19/s150x150/181615592_215309037065818_7520216790200441065_n.jpg?tp=1&_nc_ht=instagram.fath3-3.fna.fbcdn.net&_nc_ohc=ICw1tUaN_LkAX-GFvSB&edm=ABfd0MgBAAAA&ccb=7-4&oh=062eef9cafacf4056c1d485e86f4b481&oe=60C57270&_nc_sid=7bff83'},
 'username': 'billybonaros'}

Мы преобразуем данные из GraphImages в объект Pandas Dataframe, чтобы нам было удобнее работать с ними.

df**=**pd.DataFrame(js['GraphImages'])df
Image by Author

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

Создание нашего приложения Streamlit

Исходный код

Прежде чем продолжить, убедитесь, что у вас установлена Streamlit с помощью следующей команды.

pip install streamlit

Начните с создания файла .py и импорта необходимых библиотек для этого проекта. Давайте назовем наш файл main.py.

import streamlit as st
 
import requests
import numpy as np
import pandas as pd
import os
import json
import pandas as pd
import numpy as np
import re
from datetime import datetime
import string

Теперь нам нужно дать нашему приложению заголовок и создать форму.

st.title('Инстаграм Дашборд')
 
 
with st.form(key='my_form'):
 
# st.text_input создает форму для ввода текста
    username = st.text_input(label='Введите имя пользователя')
 
# st.form_submit_button создает кнопку отправки
    submit_button = st.form_submit_button(label='Отправить')

Верите или нет, наша стартовая страница готова! Мы можем добавить много других типов форм, но нам нужны только форма для ввода текста и кнопка отправки. Вы можете узнать больше в этом шпаргалке.

Чтобы запустить наше приложение, вам нужно ввести следующее в директории проекта:

streamlit run main.py

Если вы получили следующий вывод, это означает, что ваше приложение работает.

You can now view your Streamlit app in your browser.  Local URL: http://localhost:8501
  Network URL: [http://192.168.1.7:8501](http://192.168.1.7:8501)

Чтобы получить доступ к приложению, перейдите по ссылке http://localhost:8501

Image by Author

Довольно круто, не так ли?

Вывод

Для продолжения нам нужно только определить, была ли нажата кнопка отправки. Это можно сделать с помощью оператора if, а затем внутри него мы добавим наш код для вывода.

Streamlit позволяет добавлять много разных типов вывода, но мы будем использовать только следующие:

  • Текст: st.write('Текст')
  • Заголовок: st.title('Текст')
  • Заголовок: st.header('Текст')
  • Подзаголовок: st.subheader('Текст')
  • Таблица: st.table(dataframe)
  • Изображение: st.image('путь_к_изображению')
  • Гистограмма: st.bar_chart(data)

Во-первых, давайте получим данные из js['GraphProfileInfo'] и покажем полное имя пользователя, биографию, количество постов и является ли это бизнес-аккаунтом или нет. Затем мы можем загрузить изображение из profile_pic_url и показать аватар пользователя.

if submit_button:
 
#перед запуском скрипта парсинга
#мы проверяем, существует ли каталог, чтобы не парсить данные
#пользователя, у которого уже есть данные
#это поможет нам лучше тестировать приложение, потому что
#данные будут загружаться быстро и мы не будем заблокированы Instagram
#из-за слишком частого парсинга
 
    if not os.path.exists(f'{username}'):
        os.system(f'instagram-scraper "{username}" --profile-metadata  --media-metadata  --media-types none')
 
    js = json.load(open(f'{username}/{username}.json', encoding='utf-8'))
    df=pd.DataFrame(js['GraphImages'])
 
 
 
#получаем profile_pic_url из json
    prof_pic=js['GraphProfileInfo']['info']['profile_pic_url']
 
 
#загружаем изображение в созданную мной папку static
    response = requests.get(prof_pic)
    filename="static/image.jpg"
    with open(filename, "wb") as f:
        f.write(response.content)
 
#показываем полное имя
    st.write(f"Полное имя: {js['GraphProfileInfo']['info']['full_name']}")
 
 
#мы можем форматировать вывод в любое количество столбцов, используя columns
#и вместо st. мы используем column_name. для отображения вывода в
#выбранном столбце. Здесь мы разделяем вывод на 2 столбца
#в col1 будет изображение, а в col2 - информация.
 
    col1, col2 = st.columns(2)
    col1.image(filename)
    col2.write(f"Биография: {js['GraphProfileInfo']['info']['biography']}")
    col2.write(f"Это бизнес-аккаунт: {js['GraphProfileInfo']['info']['is_business_account']}")
    col2.write(f"Количество постов: {js['GraphProfileInfo']['info']['posts_count']}")

Хорошая вещь в Streamlit заключается в том, что после каждого изменения вам не нужно заново запускать streamlit run main.py, а просто перейдите в правый угол и нажмите "rerun".

Изображение от автора

Давайте запустим приложение заново и снова отправим имя пользователя.

Изображение от автора

Продолжая, мы можем применить некоторые методы манипуляции данными, чтобы получить количество лайков, дату, комментарии, хэштеги из таблицы с информацией о постах (df). Также мы можем добавить в col2 показатель вовлеченности (((общее количество лайков+общее количество комментариев)/посты)/подписчики) и среднее количество постов в месяц.

#количество лайков
df['likes']=df['edge_media_preview_like'].apply(lambda x: x['count'])
#количество комментариев
df['comments']=df['edge_media_to_comment'].apply(lambda x: x['count'])
 
#преобразуем метку времени в объект datetime
df['date']=df['taken_at_timestamp'].apply(datetime.fromtimestamp)
 
#извлекаем день недели, месяц, неделю, год, год и месяц 
df['dayofweek']=df['date'].dt.dayofweek
df['month']=df['date'].dt.month
df['week']=df['date'].dt.week
df['year']=df['date'].dt.year
df['ym']=df['year'].astype(str)+df['month'].astype(str)
 
engagement_rate=(((df['likes'].sum()+df['comments'].sum())/len(df))/js['GraphProfileInfo']['info']['followers_count'])*100
 
col2.write(f"Среднее количество постов в месяц: {round(df.groupby('ym').size().mean(),2)}")
col2.write(f"Показатель вовлеченности: {round(engagement_rate,2)}%")

Мы можем добавить некоторые графики в нашу панель управления, такие как количество постов по дням недели и количество постов по месяцам.

x=df.groupby('dayofweek').size()
st.subheader('Количество постов по дням недели')
st.bar_chart(pd.DataFrame(x).rename(columns={0: 'Количество постов'}))
 
x=df.groupby('month').size()
st.subheader('Количество постов по месяцам')
st.bar_chart(pd.DataFrame(x).rename(columns={0: 'Количество постов'}))
Изображение от автора

Мое финальное приложение

Используя те же техники, о которых мы говорили выше, я создал следующее приложение. Я добавил самые часто используемые и понравившиеся хэштеги и самые популярные посты. Также я добавил сообщение об ошибке, когда скрипт парсинга не работает из-за ограничений Instagram.

import streamlit as st
 
import requests
import numpy as np
import pandas as pd
import os
import json
import pandas as pd
import numpy as np
import re
from datetime import datetime
import string
 
st.title('Инстаграм Дашборд')
 
 
with st.form(key='my_form'):
    username = st.text_input(label='Введите имя пользователя')
    submit_button = st.form_submit_button(label='Отправить')
     
 
import os
 
 
if submit_button:
    if not os.path.exists(f'{username}'):
        os.system(f'instagram-scraper "{username}" --profile-metadata  --media-metadata  --media-types none')
    try:
        js = json.load(open(f'{username}/{username}.json', encoding='utf-8'))
         
 
 
        df=pd.DataFrame(js['GraphImages'])
 
 
        prof_pic=js['GraphProfileInfo']['info']['profile_pic_url']
 
        response = requests.get(prof_pic)
        filename="static/image.jpg"
        with open(filename, "wb") as f:
            f.write(response.content)
 
    #data
        df['likes']=df['edge_media_preview_like'].apply(lambda x: x['count'])
 
        df['comments']=df['edge_media_to_comment'].apply(lambda x: x['count'])
 
        engagement_rate=(((df['likes'].sum()+df['comments'].sum())/len(df))/js['GraphProfileInfo']['info']['followers_count'])*100
 
        df['date']=df['taken_at_timestamp'].apply(datetime.fromtimestamp)
 
        df['dayofweek']=df['date'].dt.dayofweek
        df['month']=df['date'].dt.month
        df['week']=df['date'].dt.week
        df['year']=df['date'].dt.year
        df['ym']=df['year'].astype(str)+df['month'].astype(str)
 
        df['dayofweek']=df['dayofweek'].replace([0,1,2,3,4,5,6],['Пн.', 'Вт.', 'Ср.','Чт.','Пт.','Сб.','Вс.'])
 
        col1, col2 = st.columns(2)
        col1.image(filename)
        col2.write(f"Полное имя: {js['GraphProfileInfo']['info']['full_name']}")
        col2.write(f"Биография: {js['GraphProfileInfo']['info']['biography']}")
        col2.write(f"Бизнес-аккаунт: {js['GraphProfileInfo']['info']['is_business_account']}")
        col2.write(f"Количество постов: {js['GraphProfileInfo']['info']['posts_count']}")
        col2.write(f"Среднее количество постов в месяц: {round(df.groupby('ym').size().mean(),2)}")
        col2.write(f"Уровень вовлеченности: {round(engagement_rate,2)}%")
 
 
 
        x=df.groupby('dayofweek').size()
        st.subheader('Количество постов по дням недели')
        st.bar_chart(pd.DataFrame(x).rename(columns={0: 'Количество постов'}))
 
        x=df.groupby('month').size()
        st.subheader('Количество постов по месяцам')
        st.bar_chart(pd.DataFrame(x).rename(columns={0: 'Количество постов'}))
 
        def get_caption(x):
            try:
                return(x['edges'][0]['node']['text'])
            except:
                return('')
 
        df['caption']=df['edge_media_to_caption'].apply(get_caption)
 
        df['hashtags']=df['caption'].apply(lambda x: re.findall("(#\w+)",x))
 
 
 
        hashtags=df[['hashtags','likes']].explode('hashtags').groupby('hashtags').agg({'likes':['count','mean']})
        hashtags.columns=['count','average_likes']
        most_liked_hashtags=hashtags.query('count>10').sort_values('average_likes',ascending=False)
 
        col3, col4 = st.columns(2)
        col3.subheader('Самые частые хэштеги')
        col3.table(hashtags.sort_values('count',ascending=False)[['count']].head(10))
 
        col4.subheader("Самые популярные хэштеги")
        col4.table(most_liked_hashtags.sort_values('average_likes',ascending=False)[['average_likes']].head(10))
 
 
        topurls=list(df.sort_values('likes',ascending=False)['display_url'].head())
 
        toplikes=list(df.sort_values('likes',ascending=False)['likes'].head())
        topcomments=list(df.sort_values('likes',ascending=False)['comments'].head())
 
        n=1
        for i in topurls:
            response = requests.get(i)
            filename=f"static/{n}.jpeg"
            with open(filename, "wb") as f:
                f.write(response.content)
            n+=1
 
 
        col5,col6,col7,col8,col9=st.columns(5)
        col5.image("static/1.jpeg")
        col5.write(f"Лайки: {toplikes[0]}")
        col5.write(f"Комментарии: {topcomments[0]}")
 
        col6.image("static/2.jpeg")
        col6.write(f"Лайки: {toplikes[1]}")
        col6.write(f"Комментарии: {topcomments[1]}")
 
        col7.image("static/3.jpeg")
        col7.write(f"Лайки: {toplikes[2]}")
        col7.write(f"Комментарии: {topcomments[2]}")
 
        col8.image("static/4.jpeg")
        col8.write(f"Лайки: {toplikes[3]}")
        col8.write(f"Комментарии: {topcomments[3]}")
 
        col9.image("static/5.jpeg")
        col9.write(f"Лайки: {toplikes[4]}")
        col9.write(f"Комментарии: {topcomments[4]}")   
         
    except:
        st.error('Достигнут лимит Instagram.')
Изображение от автора Изображение от автора

Подведение итогов

Streamlit - это простой и профессиональный способ создания веб-приложений. Цель этого поста - вдохновить вас на создание собственного мощного приложения. Экспериментируйте с ним, используйте машинное обучение, получайте основные цвета изображений, находите лучшие слова для использования, и т.д.

Оригинальная публикация на https://predictivehacks.com.