CoderCastrov logo
CoderCastrov
Стримлит

Как создать приложение Streamlit для парсинга профилей на Github

Как создать приложение Streamlit для парсинга профилей на Github
просмотров
6 мин чтение
#Стримлит
Table Of Content

В этом руководстве мы создадим веб-приложение с использованием Streamlit, которое будет парсить информацию о пользователе на GitHub. Оно будет отображать основную информацию и некоторые из его последних репозиториев. Для парсинга веб-страниц мы будем использовать Beautiful Soup.

A screenshot of the app

Если вы хотите узнать, как парсить веб-сайты с помощью Selenium, ознакомьтесь с моим предыдущим руководством. В этом руководстве мы сосредоточимся на Beautiful Soup. Руководство будет разделено на две части. В первой части будет рассказано о парсинге веб-страниц с использованием Beautiful Soup, а во второй части будет рассказано о том, как использовать полученные данные и Streamlit для создания веб-приложения.

Репозиторий: https://github.com/rahulbanerjee26/githubScraper

Онлайн-версия: https://github-scrape.herokuapp.com/

Установка необходимых библиотек

Сначала нам нужно установить библиотеки, которые мы будем использовать. Я настоятельно рекомендую создать виртуальное окружение перед установкой библиотек.

python -m virtualenv venv  # настройте виртуальное окружениеvenv/Scripts/actiavte # активируйте виртуальное окружениеpip install beautifulsoup4 , streamlit

Парсинг данных с GitHub

Импортируем все необходимые библиотеки, то есть bs4, request, pandas. Определим функцию, которая принимает имя пользователя в качестве параметра.

from bs4 import BeautifulSoupimport requestsimport pandas as pddef getData(userName):
    pass

URL «_https://github.com/{user_name}?tab=repositories_» содержит информацию о пользователе и его последних общедоступных репозиториях. Мы будем использовать библиотеку requests для получения содержимого страницы.

url = "https://github.com/{}?tab=repositories".format(userName)page = requests.get(url)print(page.content) #отображает html

Затем мы создаем экземпляр BeautifulSoup и передаем page.content в качестве параметра. Создаем пустой словарь для хранения информации о пользователе.

soup = BeautifulSoup(page.content , 'html.parser')info = {}

Мы будем парсить следующую информацию

  • Полное имя
  • Изображение
  • Количество подписчиков
  • Количество пользователей, на которых подписан
  • Местоположение (если существует)
  • URL портфолио (если существует)
  • Название репозитория, ссылка на репозиторий, последнее обновление репозитория, язык программирования репозитория, описание репозитория

Перед продолжением вы можете ознакомиться с CSS-селекторами атрибутов

Полное имя

Полное имя находится внутри элемента с классом "vcard-fullname". Мы используем метод .find() из библиотеки Beautiful Soup и передаем ему имя класса.

#full Nameinfo['name'] = soup.find(class_ = 'vcard-fullname').get_text()

Метод .get_text() извлекает соответствующий текст из элемента.

Изображение

Аналогично полному имени, изображение находится внутри элемента с классом "avatar-user".

#imageinfo['image_url'] =  soup.find(class_ = 'avatar-user')['src']

Поскольку нас интересует только источник изображения, мы сохраняем только значение атрибута href.

Подписчики/Подписки

Чтобы получить информацию о подписчиках/подписках, мы используем CSS-селекторы атрибутов. Если вы воспользуетесь инструментом "Инспектор элементов" на количестве подписчиков и пользователей, которых вы подписаны, вы заметите, что они имеют тег href, в котором содержатся слова "подписчики" и "подписки" соответственно. Мы будем использовать метод .select_one() из библиотеки Beautiful Soup, чтобы получить необходимые данные.

#followers and follwoinginfo['followers'] = soup.select_one("a[href*=followers]").get_text().strip().split('\n')[0]info['following'] = soup.select_one("a[href*=following]").get_text().strip().split('\n')[0]

Поскольку нас интересует только число, нам нужно обработать текст и извлечь из него число.

Местоположение и URL портфолио

При изучении местоположения и URL вы заметите, что они хранятся внутри тега <li> и имеют атрибут 'itemprop'. Значение 'itemprop' для местоположения содержит слово 'home', а для URL - 'url'. Убедитесь, что регистр строки совпадает. Мы будем использовать метод .select_one(), чтобы получить соответствующую информацию.

# Местоположение
try:
   info['location'] =             soup.select_one('li[itemprop*=home]').get_text().strip()
except:
   info['location'] = ''# URL
try:
   info['url'] =  soup.select_one('li[itemprop*=url]').get_text().strip()
except:
   info['url'] = ''

Поскольку не все пользователи могут указывать свое местоположение и URL, мы должны поместить наш код в блок try, except.

Последние открытые репозитории пользователя

Все репозитории хранятся внутри родительского элемента с классом "source". Сначала мы получаем родительский элемент. Нам также потребуется объявить пустой список для хранения информации о репозиториях.

# Получаем репозитории в виде таблицы
repos = soup.find_all(class_ = 'source')
repo_info = []

Ниже приведены элементы, в которых вы найдете необходимую информацию:

  • Название репозитория хранится внутри тега <a> с атрибутом 'itemprop', содержащим слово 'codeRepository'.
  • Ссылка на репозиторий может быть сформирована в следующем формате: 'https://github.com/{имя_пользователя}/{название_репозитория}'.
  • Дата последнего обновления репозитория находится внутри тега 'relative-time', т.е. <relative-time>.
  • Язык программирования репозитория находится внутри тега <span> с атрибутом 'itemprop' со значением 'programmingLanguage'.
  • Описание репозитория находится внутри тега <p> с атрибутом 'itemprop' со значением 'description'.

Вот фрагмент кода для получения информации о репозиториях:

for repo in repos:
    # Название и ссылка репозитория
    try:
        name = repo.select_one('a[itemprop*=codeRepository]').get_text().strip()
        link = 'https://github.com/{}/{}'.format(userName,name)
    except:
        name = ''
        link = ''
    
    # Дата последнего обновления репозитория
    try:
        updated = repo.find('relative-time').get_text()
    except:
        updated = ''
    
    # Язык программирования
    try:
        language = repo.select_one('span[itemprop*=programmingLanguage]').get_text()
    except:
        language = ''
    
    # Описание репозитория
    try:
        description = repo.select_one('p[itemprop*=description]').get_text().strip()
    except:
        description = ''

Теперь нам нужно сохранить информацию в словаре и добавить его в ранее созданный пустой список. Затем мы преобразуем его в таблицу данных, чтобы ее можно было использовать в Streamlit.

repo_info.append({'name': name ,
     'link': link ,
     'updated ':updated ,
     'language': language ,
     'description':description})
repo_info = pd.DataFrame(repo_info)
return info , repo_info

Если вы дочитали до этого места, молодец! 👏 👏

Теперь мы перейдем к части с использованием Streamlit.

Приложение Streamlit

Введите 'streamlit hello' в командной строке, чтобы проверить, что вы правильно установили Streamlit. Оно должно открыть веб-приложение в браузере.

Создайте файл с именем 'app.py', в котором будет содержаться необходимый код для Streamlit.

Сначала нам нужно выполнить необходимые импорты, то есть Streamlit и нашу функцию для получения данных пользователя.

import streamlit as st
from scrape import getData

Мы будем использовать метод .title() для отображения заголовка и метод .text_input() для получения имени пользователя.

st.title("Github Парсер")
userName = st.text_input('Введите имя пользователя Github')

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

Получив имя пользователя, мы используем ранее созданную функцию getData. Мы помещаем ее в блок try-except, так как вводом может быть недопустимое имя пользователя. Мы используем метод .subheader() для отображения информации о пользователе, кроме изображения, для которого мы используем метод .image(). Чтобы отобразить таблицу, содержащую информацию о репозиториях, мы используем метод .table().

if userName != '':
    try:
        info, repo_info = getData(userName)
        for key, value in info.items():
            if key != 'image_url':
                st.subheader(
                    '''{}: {}'''.format(key, value)
                )
            else:
                st.image(value)
        st.subheader("Последние репозитории")
        st.table(repo_info)
    except:
        st.subheader("Пользователь не существует")

Вы успешно создали веб-приложение Streamlit для парсинга информации о пользователе GitHub 😎 😎 Если вы дошли до этого момента, я настоятельно рекомендую вам развернуть свое приложение. Вы можете ознакомиться с моей статьей о том, как развернуть приложения Streamlit с помощью Heroku.


Недавно я создал блог с использованием WordPress, мне было бы очень приятно, если вы его посетите 😃

Python Project Tutorials — Улучшите свое резюме/портфолио с помощью этих учебников по проектам на Python.

Разверните свое веб-приложение машинного обучения с использованием Streamlit Sharing В моих предыдущих статьях я говорил о создании...

realpythonproject.com

Свяжитесь со мной на LinkedIn

Rahul Banerjee — Инженер-продуктовый стажер — EY | LinkedIn

Просмотрите профиль Рахула Банерджи на LinkedIn, крупнейшем в мире сообществе специалистов. У Рахула есть 4 работы, указанные на их...

www.linkedin.com

Свяжитесь со мной в Twitter