Механика
Скрипт для раскрутки назовём для краткости "робопёс". Представим, что этот скрипт от лица собачьего аккаунта периодически собирает посты по хэштегам на собачьи темы и ставит лайки таким постам. Какая-то часть авторов этих постов заинтресуется, кто им поставил лайк, и зайдёт на страницу собачьего аккаунта. Ну а дальше, как пойдёт. Кто-то пролистает пару экранов вниз и пойдёт дальше. Кто-то поставит робопсу пару ответных лайков (что тоже неплохо, лайки увеличивают охват постов). А если аккаунт понравится (что не исключено, ибо пёс весьма харизматичен), может и подписаться.
Осторожно: "масслайкинг"
Надо отметить, что такие действия называются "масслайкинг" и не особо привествуются Instagram. При появлении подозрительной робопёсей активности Instagram сначал вынесет несколько предупреждений, а потом может и навечно забанить аккаунт. Кстати, под запрет попадает и ручной масслайкинг (т.е. если лайкает не автоматизированный сервис, а лично Вы).
Есть мнение, что масслайкинг сейчас не особо работает. Ну что же, заодно и проверим.
Сервисы и библиотеки для масслайкинга и массфоловинга
Несмотря всё вышеизложенное, живут и процветают десятки различных сервисов для масслайкинга и массфоловинга (интересуюшиеся могут посмотреть здесь, здесь или погуглить самостоятельно). Это намекает на то, что масслайкинг всётаки работает.
Получается, как с сексом. Вроде все занимаются, но обсуждать в приличном обществе не принято. Опять же в интернетах можно найти эмпирически установленные ограничения для масслайкинга. Если робопёс не будет их превышать, то в бан его отправить не должны. Для молодых (менее полугода от даты регистрации) аккаунтов это не более 30 лайков в час или 720 в день.
Для питонистов есть специальные библиотеки. Наиболее известная - Instapy (12 тыс. звезд на Github, на минуточку). Есть менее известные. Кстати, недавно на Хабре была статья в которой разбирается очень даже достойная библиотека instabot. Но использовать их "в лоб" для автойлакинга по хэштегам лично я бы не стал. По нижеследующей причине.
Что не так с хэштегами
Проблема с высокачастотными хэштегами состоит в том, что они сильно зашумлены разным спамом (с которым Instagram тоже борется, но явно не особо успешно).
Коммерческие аккаунты или просто пользователи, которые хотят максимально раскрутиться, добавляют высокочастотные хэшеги к любым своим постам. И это, к сожалению, общепринятая практика.
Робопёс не хочет лайкать что не попадя, а готов дарить лайки исключтельно лайкам (и всем прочим породам собак), но никак не домам! А значит нужны какие-то дополнительные инструменты для отсеивания ненужного контента.
Анализ фото постов с помощью нейросети
По идее "левые" фотки к постам можно отсечь с помощью анализа изображений нейросетью. То есть робопёс должен скачивать картинку поста, и определять, есть ли на ней собака. Если есть - лайкать, если нет - пропускать. Такая задача называется Object Detection, для её решения есть специальные инструменты, а именно SSD детекторы.
На заглавной картинке к посту - пара собачьих фото, по которым прошелся SSD детектор на основе MobileNet v.2, обученный на датасэте COCO2017. Робопёс будет использовать архитектуру MobileNet, поскольку она мало весит и быстро работает на обычной машине без GPU с приемлемой точностью. Кстати, на обоих фото собака определена нейросетью с вероятностью 94%.
Для желающих самостоятельно потестить, как работает SSD на произвольном посте выкладываю здесь кусок кода на python. Для удобства выложил скрипт на Github, но файл с весами не влез, придётся скачивать отдельно, в репозиории есть инструкция.
Код
import cv2
import json
from datetime import datetime
import requests
import numpy as np
import pandas as pd
from matplotlib import pyplot as plt
def id_class_name(class_id, classes):
for key, value in classes.items():
if class_id == key:
return value
# Здесь вбиваем нужный пост
shortcode = 'CJ.........'
classNames = {}
with open('models/coco2017_labels.txt', 'r+', encoding='utf-8') as file:
for line in file:
key = int(line.split(':')[0])
value = line.split(':')[1]
classNames[key] = value.strip()
COLORS = np.random.uniform(0, 255, size=(len(classNames), 3))
s = requests.session()
r = s.get(f'https://www.instagram.com/p/{shortcode}/?__a=1', headers = {'User-agent': 'bot'})
url = r.json()['graphql']['shortcode_media']['display_resources'][0]['src']
resp = requests.get(url, stream=True)
image = np.asarray(bytearray(resp.content), dtype="uint8")
image = cv2.imdecode(image, cv2.IMREAD_COLOR)
image_height, image_width, _ = image.shape
frame_resized = cv2.resize(image,(300,300))
model = cv2.dnn.readNetFromTensorflow('models/frozen_inference_graphод.pb',
'models/ssd_mobilenet_v2_coco_2018_03_29.pbtxt')
model.setInput(cv2.dnn.blobFromImage(frame_resized, size=(300, 300), swapRB=True))
output = model.forward()
detections = output[0, 0, :, :]
detections = detections[detections[:,2].argsort()]
for detection in detections:
confidence = detection[2]
class_id = int(detection[1])
class_name = id_class_name(class_id, classNames)
if (confidence > 0.3):
box_x = int(detection[3] * image_width)
box_y = int(detection[4] * image_height)
box_width = int(detection[5] * image_width)
box_height = int(detection[6] * image_height)
cv2.rectangle(image, (box_x, box_y), (box_width, box_height), COLORS[class_id], thickness=2)
label = class_name + ": " + str(round(confidence, 2))
labelSize, baseLine = cv2.getTextSize(label, cv2.FONT_HERSHEY_DUPLEX, 0.5, 1)
yLeftBottom_ = max(box_y, labelSize[1])
cv2.rectangle(image, (box_x, box_y + labelSize[1]), (box_x + labelSize[0], box_y), COLORS[class_id], cv2.FILLED)
cv2.putText(image, label, (box_x, box_y + labelSize[1] - baseLine//2), cv2.FONT_HERSHEY_DUPLEX, 0.5, (255, 255, 255))
plt.figure(figsize=(8,8))
plt.axis("off")
plt.imshow(cv2.cvtColor(image, cv2.COLOR_BGR2RGB))
# Если хотите сохранить файл с обнаруженными классами в виде файла - раскомментируйте строку ниже
#plt.savefig(f'{shortcode}.png')
Для запуска ещё потребуется установить библиотеку OpenCV и несколько других. Все они импортируются в начале скрипта, если чего-то не будет хватать, доставьте через pip или conda install.
Для скачивания информации о посте используется запрос вида /?__a=1 к OpenAPI Instagram. Пока этот запрос работает без авторизации, но инста каждый день чего-нибудь да закручивает, так что наверное, скоро и его закроют. Больше о структуре данных, которую использует Instagram, можно опять же почерпнуть здесь.
Надо сказать, что собаки данной реализацией нейросети определяются корректно не всегда. Вот например:
Дело в том, что ракурс на фото выбран довольно необычный - нос собаки похож на клюв какой-то птицы вроде тукана. То есть в реальных условиях часть годного контента будет неминуемо отбракована, робопёс будет лайкать не всех собак. Но в рамках решаемой задачи с этим вполне можно смириться.
Продолжение следует. В ближайшее время разверну робопса на локальной машине, поавтолайкаю, соберу статистику по отклику на лайки и отпишусь о результатах.
Alpx
Прикольно — пес, который смог на всех обмасслаять)
Walker2000 Автор
Не, этот слишком дружелюбный. Не лает, только лайкает )
VasilyevaV
классная языковая игра!)
Walker2000 Автор
На самом деле, у Уральских пельменей что-то подобное было. «Современные собаки не лают, а лайкают» )