На своем личном сайте я отображаю «живой» счетчик общего количества подписчиков на различных платформах: LinkedIn, GitHub, YouTube, Instagram, Twitter, Medium и Facebook. Я стараюсь геймифицировать социальные сети для себя, и точный подсчет подписчиков и данных играет ключевую роль в достижении этой цели.
Смотрите вживую здесь.

«Живой» счетчик подписчиков на моем сайте.
В текущей версии я вручную захожу на каждую платформу, суммирую количество подписчиков и обновляю цифру во Framer. Но я же не просто так работаю data scientist’ом и люблю экспериментировать! Давайте попробуем найти более изящное решение. Моя цель — создать автономный скрипт, который будет автоматически собирать статистику с каждой платформы и подсчитывать итоговое значение.
Автоматизация процесса сбора данных
Попытка 1: Использование сторонних платформ
Сначала я подумал о том, чтобы воспользоваться сторонними сервисами, которые могли бы собрать все данные в одном месте за меня. Такие платформы, как Hootsuite и Funnel.io, предлагают подобные инструменты, но они довольно дорогие и ориентированы на малый бизнес, готовый инвестировать в аналитику. В моем случае мне нужен всего лишь простой скрипт, который просто суммирует количество подписчиков.
Кроме того, у таких крупных платформ есть серьезный недостаток: для работы с ними нужно «подключить» все свои аккаунты, что, по сути, означает передачу им своих паролей и снижение уровня безопасности.
Этот путь явно не подходит для моей цели.
Попытка 2: Использование API социальных сетей
Это второй «с конца» вариант. У каждой социальной сети есть свой API, своя система тарификации, набор функций и ограничения по количеству запросов. Например, существуют Twitter API, Facebook Graph API, Unsplash API и многие другие.
Хотя такие API достаточно безопасны, поскольку они предоставляются самими платформами, их настройка и поддержка требуют огромного количества времени. Кроме того, для работы с ними часто нужно привязывать банковскую карту к разным сервисам, что мне не нравится.
Еще один серьезный минус — вся активность привязана к моему аккаунту, а это повышает риск блокировки за возможное нарушение правил использования API.
Определённо не то, что мне нужно.
Попытка 3: Использование библиотек Python
Давайте проверим, пробовал ли кто-то уже решить эту проблему до меня.
Похоже, кто-то написал API для LinkedIn! Также есть Pytube — API для YouTube.
Однако с Twitter все сложнее — после того, как Илон Маск приобрёл сесть, они заблокировали сторонние API, и теперь за доступ придется платить. Medium, похоже, тоже предоставляет API.
Но есть серьезный недостаток: мне придется поддерживать отдельную версию библиотеки для каждой платформы, с которой я хочу получать данные.
Кроме того, некоторые библиотеки требуют ввода логина и пароля, что не только небезопасно, но и может привести к блокировке моих аккаунтов. А еще мне придется следить за обновлениями этих библиотек и переписывать код каждый раз, когда соцсети меняют свой интерфейс.
При этом очевидно, что если просто открыть ссылки на мои профили, я сразу вижу количество подписчиков. Думаю, есть более простой способ решить эту задачу!
Попытка 4: Парсинг и HTML-скрейпинг (Puppeteer, Chromium и др.)
А вот здесь уже начинается настоящая разработка. Я нашёл код, который получает количество подписчиков в Twitter.
from bs4 import BeautifulSoup import requests handle = input('Input your account name on Twitter: ') temp = requests.get('https://twitter.com/'+handle) bs = BeautifulSoup(temp.text,'lxml') try: follow_box = bs.find('li',{'class':'ProfileNav-item ProfileNav-item--followers'}) followers = follow_box.find('a').find('span',{'class':'ProfileNav-value'}) print("Number of followers: {} ".format(followers.get('data-count'))) except: print('Account name not found...')
Посмотрим, сработает ли это!

Окей, это определенно не сработало… Кроме того, на некоторых сайтах всплывающие окна с просьбой войти или зарегистрироваться перекрывают интересующий меня контент.

Мне просто нужен способ автоматически открывать Chrome и переходить на сайты, где я уже авторизован. Похоже, что использование автоматизированных браузеров вроде Puppeteer мне не подойдёт, поскольку такие решения плохо масштабируются.
Попытка 5: Использование Open-Interpreter
С учетом всего вышесказанного, давайте попробуем автоматически открыть Chrome и получать нужный контент. Недавно я узнал, что Open-Interpreter умеет запускать приложения, так что попробуем попросить его посчитать моих подписчиков на LinkedIn.

Это здорово — страница открывается правильно, но проблема в том, что нет способа извлечь информацию с экрана. Open-Interpreter не позволяет получить доступ к HTML-коду страницы, а его возможности по созданию скриншотов все еще нестабильны.
Кстати, я также попробовал JS CLI-инструмент capture-website, который хорошо делает скриншоты, но столкнулся с теми же проблемами, что и Puppeteer и другие аналогичные инструменты.
www.npmjs.com/package/capture-website
Итак, мы можем автоматически переходить на страницы и делать скриншоты вручную. Что дальше?
Попытка 6: Использование AppleScript и Tesseract (OCR)
Мы уже знаем, что можно автоматически переходить на страницы с помощью AppleScript — именно такой механизм работал в Open-Interpreter. Теперь осталось понять, как автоматически делать скриншоты страниц после загрузки.
После этого мы можем использовать OCR (оптическое распознавание символов), например, библиотеку Tesseract, чтобы извлекать текст с экрана.
Это отличное решение, потому что если интерфейс социальных сетей изменится, наш скрипт все равно сможет адаптироваться, не завися от обновлений библиотек или API.
План готов, приступаем к написанию скрипта!
YOUTUBE_LINK = 'https://www.youtube.com/channel/UC-uTdkWQ8doqRwXBlkH67Dw' LINKEDIN_LINK = 'https://www.linkedin.com/in/jackblair876/' GITHUB_LINK = 'https://github.com/JackBlair87' INSTAGRAM_LINK_MAIN = 'https://www.instagram.com/jack.blairr/' INSTAGRAM_LINK_SECONDARY = 'https://www.instagram.com/jack.bl.ai.rt/' TWITTER_LINK = 'https://twitter.com/JackBlair87' MEDIUM_LINK = 'https://medium.com/@jackblair87' FACEBOOK_LINK = 'https://www.facebook.com/jack.blair.94043/' PROFILE_LINKS = [{ 'link' : YOUTUBE_LINK, 'platform' : 'youtube', 'account' : 'main' }, { 'link' : LINKEDIN_LINK, 'platform' : 'linkedin', 'account' : 'main' }, { 'link' : GITHUB_LINK, 'platform' : 'github', 'account' : 'main' }, { 'link' : INSTAGRAM_LINK_MAIN, 'platform' : 'instagram', 'account' : 'main' }, { 'link' : INSTAGRAM_LINK_SECONDARY, 'platform' : 'instagram', 'account' : 'art' }, { 'link' : TWITTER_LINK, 'platform' : 'twitter', 'account' : 'main' }, { 'link' : MEDIUM_LINK, 'platform' : 'medium', 'account' : 'main' }, { 'link' : FACEBOOK_LINK, 'platform' : 'facebook', 'account' : 'main' }] TOTAL_FOLLOWERS = 0
Сначала формально определим каждый из профилей, которые хотим учитывать. Добавим в словарь переменную account, чтобы можно было суммировать подписчиков с нескольких профилей на одной платформе, например, основного и альтернативного аккаунтов в Instagram.
def take_screenshots(): for link in tqdm(PROFILE_LINKS): temp_link = 'screenshots/' + link['platform'] + '[' + link['account'] + '].png' #join this path with the current path full_link = os.path.join(os.getcwd(), temp_link.replace(' ', '\ ')) print(full_link) r = applescript.run(f""" tell application "Google Chrome" activate open location "{link['link']}" set thePath to "{full_link}" delay 5 do shell script ("screencapture " & thePath) end tell """) #save it to the desktop image1 = pyautogui.screenshot(full_link) image1.save(full_link) r = applescript.run(f""" tell application "Google Chrome" try tell window 1 of application "Google Chrome" to ¬ close active tab end try end tell """)
Теперь мы можем определить функцию, которая будет перебирать список ссылок, переходить на страницу, делать скриншот с помощью pyautogui и сохранять его. Далее используем библиотеку Tesseract OCR, чтобы извлечь текст из скриншотов.
def extract_follower_count(text, platform): platform_mappings = { 'youtube': 'subscribers', 'instagram': 'followers', 'twitter': 'followers', 'facebook': 'friends', 'github': 'followers', 'linkedin': 'followers', 'medium': 'followers' } if platform in platform_mappings: keyword = platform_mappings[platform] count_text = text.split(keyword)[0] count = list(map(str.strip, count_text.split()))[-1] print(f'{platform.capitalize()} count:', count) return convert_youtube_strings_to_values(count) else: print('Platform not supported') return None def ocr_image(image_path, platform): global TOTAL_FOLLOWERS # Load image img = cv2.imread(image_path) # Convert image to grayscale gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # Apply threshold to convert to binary image # threshold_img = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)[1] # Pass the image through pytesseract text = pytesseract.image_to_string(gray) # Print the extracted text # print(text) #save to a text file with open('text_files/' + image_path.split('/')[1].split('.')[0] + '.txt', 'w') as f: f.write(text) TOTAL_FOLLOWERS += extract_follower_count(text.lower(), platform) return text
Пример получившегося скриншота:

Пример извлеченного текста:
GM OMOUR®) @ oO © © S CG GG CEG 9 sBeg x + 23 https://www.linkedin.com/in/jackblair876/ A small AppleScript to take a screenshot every 30 seconds for 8... a: 3 Try 1 month offer i ‘in| Q Search aa _ : yt gist.github.com My Network Messaging Notifications For Business Premium for $ Profile language V4 English Public profile & URL V4 www.linkedin.com/in/jackblair876 Ad ee Get the latest jobs and industry news i zm Purdue University College Jack Blair 9 , of Engineering \\ @ PURDUE '26 | @ TJHSST '22 | °. 2x Founder | & Al Researcher | ® Full Stack Developer | »# Eagle Scout Jack, explore relevant opportunities San Francisco Bay Area - Contact info with Twilio My Portfolio (7 ( Follow - \ ) 3,706 followers - 500+ connections t opento J Add profile section )( More ) Open to work o Ron Nachum - ‘st Software Engineer, System Engineer, Mechanical Engineer and Project Engineer roles Founder | Harvard CS/Stat | Show details Other similar profiles ronnachum.com Rohin Inani - 2nd Incoming SWE Intern @ Analytics © Private to you $ 845 profile views ul, 4,125 post impressions Q. 339 search appearances Ambarella | CS @ Purdue... Discover who's viewed your Check out who's engaging with See how often you appear in profile. your posts. search results. a* Connect Past 7 days . Kushagr Khanna - ‘st A Messagin: ow BA Show all analytics > 9 . we ging
extract_follower_count() находит правильное слово (followers, subscribers, friends) для каждой платформы и извлекает число, которое стоит перед этим словом. Это уже работает довольно хорошо, но для улучшения можно добавить LLM на этапе постобработки.
Давайте посмотрим, как справляется этот скрипт…

По состоянию на 8 мая 2024 года скрипт идеально извлекает количество подписчиков, даже при нескольких попытках.

Полный исходный код находится в репозитории. Вы сможете клонировать его и добавить любые ссылки по своему желанию. Я назвал этот проект HyperHerd, так как он связан с «собиранием» (herding) подписчиков.
Что можно улучшить
Размышления и ограничения
Этот скрипт работает очень хорошо. Позже мне нужно будет провести бенчмаркинг, но по моим тестам он уже достаточно стабилен.
Однако у него есть несколько недостатков:
- Работает только на Mac.
- Компьютер должен быть включен, а пользователь — запускать скрипт вручную.
- Во время работы скрипта пользователь не может использовать компьютер.
- Проблемы с интернетом (медленный Wi-Fi или его отсутствие) приводят к сбоям.
- Нет возможности отслеживать динамику подписчиков на каждой платформе.
Идеальный вариант — запускать код на сервере, по расписанию, и сохранять данные в облачную базу данных, чтобы затем их можно было запрашивать или отправлять в другие системы.
Но поскольку для работы скрипта требуется, чтобы пользователь был авторизован на всех сервисах, а также имел корректные cookies и сессионные данные, лучшим решением остается локальный запуск на устройстве.
Улучшения
Чтобы копнуть глубже, я хочу исследовать использование Chrome-расширения вместо AppleScript для этого процесса. Насколько я понимаю, у этого подхода есть несколько ключевых преимуществ.
Наши основные операции — открыть Chrome, открыть ссылку в новой вкладке, сделать скриншот веб-страницы (или спарсить HTML), выполнить OCR и разобрать ответ. Поскольку у Tesseract есть библиотека для JavaScript, все вышеперечисленное возможно выполнить с помощью расширения Chrome.
Это решит проблему кроссплатформенности и устранит неудобства, связанные с тем, что во время работы скрипта нельзя пользоваться компьютером. Кроме того, мы сможем запускать расширение в фоновом режиме через определенные интервалы времени и сохранять данные в LocalStorage (или Firebase) для отслеживания количества подписчиков с течением времени.
Если OCR окажется слишком ненадежным, использование расширения Chrome предоставит доступ к сырому HTML. В сочетании с кодом для конвертации HTML в Markdown это позволит экспортировать и анализировать данные, значительно повышая точность.
ссылка на оригинал статьи https://habr.com/ru/articles/897486/
Добавить комментарий