Робот-самурай ч.2. Хокку-бот для постинга в ВК / Хабр

Привет! Ранее я рассказал, как я создал Телеграм-бота, который пишет хокку и подбирает пикчу в тему. В этой статье расскажу, как я научился фильтровать изображения по размеру и про работу с vk_api. Прошлая статья вышла немного скомканной, поэтому в этой статье заново рассмотрим весь принцип работы.

Цели проекта

Строго говоря, бот не пишет хокку. Он всего лишь составляет трёхстишие из уже имеющихся строк, вставляя их рандомно. Таким образом, мы получаем не совсем осмысленное произведение, хотя если посмотреть на переводы оригинальных хокку, то наши отличаются не сильно. Буду рад любым идеям, как нам реализовать правильное строение хокку по слогам (Строение хокку).

Для меня самым важным тут является не сам принцип построения хокку (хотя и хотелось бы улучшить качество самих стихов), а работа с API и requests. Поэтому, этот бот больше нужен для моего обучения, развития и развлечения (все таки бот мемный). Перед тем как начать, хочу напомнить, что исходный код вы можете увидеть на GitHub, а результат работы посмотреть в Телеграм-канале и группе ВК

Как составить «хокку»?

Стихи хокку или хайку это традиционные японские трехстишия, составленные по определённой структуре. Предвидя споры в комментариях (хокку или хайку), оставлю ссылку. Тут вы можете сполна познакомиться с японской поэзией.

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

Для этого я заранее собрал базу из традиционных японских хокку и имён авторов, откуда бот будет брать инфу. После всех фильтрации и сбора популярных японских имён (надеюсь это не расизм) мы получаем такие документы:

Количество вариантов

Чтобы посчитать количество вариантов нужно обратиться к комбинаторике. Наш алгоритм каждую итерацию берёт случайную строку. Так возможны варианты, когда у нас все 3 строки повторяются.

Одинокий сверчок.

Одинокий сверчок.

Одинокий сверчок.

— Дао Дао Дао 1111 г. н.э.

Теперь нужно немного напрячься, чтобы вспомнить, что такому варианту соответствуют размещения, в нашем случае ещё и с повторениями.

Получается, для нас это:

6,8 миллиардов различных вариантов. Если бот будет отправлять сообщения раз в 8-16 часов, то в среднем такого количества нам хватит на 9 млн лет. 🙂

Телеграм канал

Наконец, когда понятно, что и как должно работать, пришло время написать нашего бота. Изначально проект был задуман как Телеграм бот, поэтому начинаем с создания бота в BotFather. Обращаемся к классу TeleBot в библиотеке pyTelegramBotApi и заодно сохраняем имя канала.

bot = telebot.TeleBot(token = BOT_TOKEN)
CHANNEL_NAME = '@hokky_t'

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

def hokky_bot():
    f = open('hokky.txt', 'r', encoding='UTF-8')  # Открываем файл с хокку
    all_hokky = f.read().split('\n')  # Записываем каждую строчку в отдульный элемент списка
    f.close()
    f = open('names.txt', 'r', encoding='UTF-8')  # То же самое для файла с именами
    all_names = f.read().split('\n')
    f.close()
    j = 0
    print('Power on!')   
    while j < 10000:
        a = randint(0,1)  # генерируем случайное число для вставки н.э или до н.э.
        if a == 1:
            era ='до н.э.'
        else: 
            era = 'н.э'
        i =0 
        name = [1, 2, 3]
        text = [1, 2, 3]
        while i<=2: 
            name[i] = all_names[randint(1, len(all_names)-1)]  # Формируем списки из 3 строчек хокку и 3-х имён
            text[i] = all_hokky[randint(1, len(all_hokky)-1)] 
            i += 1
        message = (f'{text[0]}\n{text[1]}\n{text[2]}\n\n     - {name[0].
title()} {name[1].title()} {name[2].title()}, {randint(0, 2022)} г. {era}') j += 1 search = text[randint(0,2)] print(f'Японская живопись {search}') picture(message, search) time.sleep(randint(28800, 57600))

Из количества использования функции randint() уже можно понять, насколько качественно наш алгоритм создаёт стихи. Про предпоследние три строки расскажу далее, а пока наш код уже умеет создавать это:

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

search = text[randint(0,2)] 
print(f'Японская живопись {search}')
picture(message, search)

После всех вариантов, оптимальным оказался тот, где мы ищем картинки по запросу ‘Японская живопись + строка из хокку’

Мы передаём сам текст сообщения и поисковой запрос в функцию picture().

def picture(message, search):
    # Код для вставки своего хокку в изображение из request_photo
    # im = requests.get(request_photo('японcкая живопись', search))  
    # out = open("img.jpg", "wb")
    # out.write(im.content)
    # out.close()
    # image = Image.open('img.jpg')
    # # Создаем объект со шрифтом
    # font = ImageFont.truetype('font.name', size= int(image.width/15))
    # draw_text = ImageDraw.Draw(image)
    # draw_text.text(
    #     (int(image.width/50), int(image.height/4)),
    #     message,
    #     # Добавляем шрифт к изображению
    #     font=font,
    #     fill='#d60000') # Цвет текста
    url = request_photo(f'Японская живопись {search}')  # Функция поиска изображения
    bot.send_photo(CHANNEL_NAME, photo = url, caption = message)  # Отправляем в тг
    vk_post(url=url, message=message)  # Отправляем пост в ВК

Здесь мы вызываем функцию request_photo(). Она возвращает ссылку на случайное изображение из поискового запроса Яндекс.

Функция vk_post() является некоторым спойлером, о котором позже. «‘]+»’, req.text))) ph_list = [] for i in range(1, 10): if len(ph_links[i]) > 5: if ph_links[i][0:4] == «http»: size = ph_size(ph_links[i])[0] print(size) if size > 500: ph_list.append(ph_links[i]) print(ph_list) return ph_list[randint(0, len(ph_list) — 1)]

Тут всё просто. Сначала мы получаем код страницы по запросу в Яндекс картинках. Затем мы составляем список из всех объектов html документа, оканчивающиеся на

.jpg, после чего, через цикл фильтруем только те, которые начинаются на http. И свежеотобранные ссылки уже отправляем в функцию ph_links(), которая в свою очередь возвращает размер изображения. Мы получаем ширину картинки, после чего в новый список добавляем только те, ширина которых больше 500 пикселей. Таким образом мы отсеиваем «мыльные» картинки. И в конце функция возвращает рандомную картинку из полученного списка.

Функция ph_size отправляет запрос на url выбранной нами картинки, после чего возвращает параметр p. image.size. Введение такого фильтра очень замедлило работу бота. Также пришлось уменьшить выборку ссылок с поисковой страницы (мы берём только 10) из-за вывода системой капчи.

def ph_size(url):
    resume_header = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:66.0) Gecko/20100101 Firefox/66.0",
    "Accept-Encoding": "*",
    "Connection": "keep-alive", 
    'Range': 'bytes=0-2000000'}  
    data = requests.get(url, stream = True, headers = resume_header).content
    p = ImageFile.Parser()
    p.feed(data)   
    if p.image:
        return p.image.size 
    # (1400, 1536) 
    else: 
        return (0, 0)

Ещё одна проблема, с которой пришлось столкнуться это ошибка получения сертификата:

[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:997)

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

Пример картинки по запросу «Японская живопись ночью прилёг уснуть.»

Такой результат меня очень устраивает. Такой Телеграм-канал уже не стыдно показать друзьям и вместе посмеяться. Но как насчёт заставить бота вести одновременно несколько соцсетей. Начнём с ВК.

Группа в ВК

Самым простым способом публиковать записи в сообществе является

API VK. На питоне доступна библиотека vk_api для создания api запросов. С отправкой сообщений всё просто, можно обращаться к методу wall.post, указав айди сообщества со знаком минус. Главное, чтобы пользователь был админом, либо же использовать встроенный токен из настроек сообщества. Делается это так:

vk_session = vk_api.VkApi('LOGIN', 'PASSWORD')
vk_session.auth()
vk = vk_session.get_api()
vk.wall.post(message=message, owner_id = '-213199160') 

С отправкой фотографий всё несколько труднее. Нужно сначала загрузить фото в альбом, потом получив photo id указать его в параметре attachments.

В документации ВК подробно описано, как пользоваться этим методом. То есть нам для загрузки в альбом нужно сначала сохранить его в локальную папку. В итоге получаем такую функцию:

def vk_post(url, message):
    vk_session = vk_api.VkApi('LOGIN', 'PASSWORD')
    vk_upload = vk_api.upload.VkUpload(vk_session)
    vk_session.auth()  # Входим в аккаунт
    vk = vk_session.get_api()  # Возвращает VkApiMethod(self)
    im = requests.get(url=url)  # Скачиваем изображение
    f = open("img.jpg", "wb")
    f.write(im.content)
    f.close()
    with open ('img.jpg', 'rb') as f:
        ph = vk_upload.photo(photos=f, album_id=284394723)  # Загружаем фото в альбом
        ph_id = ph[0]['id']  # Получаем id фотографии
# Отправляем пост на стену группы
    print(vk.wall.post(message=message, owner_id = '-213199160', attachments= f'photo223988241_{ph_id}', copyright= 'https://t.me/hokky_t'))

Ура! Теперь наш бот отправляет одинаковые записи в Телеграм-канал и группу ВК. Довольно простой на первый взгляд проект дал мне немало новых знаний и умений, ещё и удовольствия получил массу. Есть некоторые идеи для новых фич, как например озвучка текста, или добавление фото не из поиска, а создание их с помощью нейросети ruDalle. В общем, есть куда стремиться.

Публикация в в

На этом в принципе всё. Жду в комментариях ваши идеи для внедрения в проект, а также замечания.

Ещё раз напомню, вот ссылки на Телеграм канал и группу ВК, а также GitHub. Подпишитесь, мне будет очень приятно!

Всем пока, до новых статей.

Бот для автопостинга VK

ВНИМАНИЕ: статья создана только в обучающих целях, я не призываю Вас использовать продукт полученный в конце урока для принесения неудобств или собственной выгоды

Что будем делать

Бота для

автопостинга

записей на стене сообщества или страницы Vk

Зачем

Для ознакомительных целей

Что нам понадобится


  • Знание ЯП Python
  • Python3
  • Модуль для работы с XML файлами
  • Python библиотеки: vk_api и time

Начнем

Для работы нам понадобится токен с разрешениями wall и offline.

Для получения токена создайте свое Standalone-приложение Vk. И сохраните его ID.

Далее перейдите по ссылке:
oauth.vk.com/authorize?client_id=IDAPP&scope=wall,offline&redirect_uri=http://api.vk.com/blank.html&response_type=token
И вместо IDAPP подставьте ID своего приложения. Или воспользуйтесь ссылкой, которую я подготовил специально для Вас.

Если все сделано правильно Вас перекинет на другой сайт, а в URL странице в GET параметре access_token будет токен, который нам и нужен, сохраняем его.

Работа XML

Для хранения настроек созданим файл формата .xml со следующем контентом:

<settings>
  <token>token</token>
  <textPost>Text post</textPost>
  <interval>120</interval>
  
  <post>
    <attachments>
      <attachment>attachment</attachment>
    </attachments>
    <copyright>copyright</copyright>
    <v>5. 122</v>
  </post>
  
  <groups>
    <group>short name group</group>
  </groups>
</settings>

Замените:

  • «token» на токен, который мы получили выше
  • «Text post» на сообщение, которое должно быть в записи
  • «attachment» на объект, который будет прикреплен к записи
  • «copyright» на ссылку источника
  • «short name group» на короткое имя(без vk.com) страницу сообщества/ пользователя, где будет проходить публикация(стена должна быть открытой для публикации)

Начнем писать код

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

import vk_api
import time
from modules import XML as moduleXml
XML = moduleXml.XML("settings")
VK = vk_api.VkApi(token=XML.parsingFile("token"))

Далее получим все короткие адреса, где будут публиковаться записи.

import vk_api
import time
from modules import XML as moduleXml
XML = moduleXml.XML("settings")
VK = vk_api.VkApi(token=XML.parsingFile("token"))
groupsId = []
groupsShortName = ""
for child in XML.parsingFile("groups", False):
    groupsShortName += child.text + ","
for group in VK.method("groups.getById", {"group_ids": groupsShortName}):
    groupsId.append(group["id"] * -1)
del groupsShortName

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

import vk_api
import time
from modules import XML as moduleXml
XML = moduleXml.XML("settings")
VK = vk_api.VkApi(token=XML.parsingFile("token"))
groupsId = []
groupsShortName = ""
for child in XML.parsingFile("groups", False):
    groupsShortName += child.text + ","
for group in VK.method("groups.getById", {"group_ids": groupsShortName}):
    groupsId.append(group["id"] * -1)
del groupsShortName
textPost = XML.parsingFile("textPost")
intervalPost = int(XML. parsingFile("interval"))

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

import vk_api
import time
from modules import XML as moduleXml
XML = moduleXml.XML("settings")
VK = vk_api.VkApi(token=XML.parsingFile("token"))
groupsId = []
groupsShortName = ""
for child in XML.parsingFile("groups", False):
    groupsShortName += child.text + ","
for group in VK.method("groups.getById", {"group_ids": groupsShortName}):
    groupsId.append(group["id"] * -1)
del groupsShortName
textPost = XML.parsingFile("textPost")
intervalPost = int(XML.parsingFile("interval"))
attachments = [attachment.text for attachment in XML.parsingFile("attachments", False)]
copyright = XML.parsingFile("copyright")
v = XML.parsingFile("v")

У нас уже есть все данные, которые нам понадобятся для публикации. Осталось только сделать функцию для публикации и цикл, который будет вызывать функцию публикации.

Сначала сделаем цикл, а функцию оставим пустой. Так же код будет работать, только если будет запущен из консоли.

import vk_api
import time
from modules import XML as moduleXml
XML = moduleXml.XML("settings")
VK = vk_api.VkApi(token=XML.parsingFile("token"))
groupsId = []
groupsShortName = ""
for child in XML.parsingFile("groups", False):
    groupsShortName += child.text + ","
for group in VK.method("groups.getById", {"group_ids": groupsShortName}):
    groupsId.append(group["id"] * -1)
del groupsShortName
textPost = XML.parsingFile("textPost")
intervalPost = int(XML.parsingFile("interval"))
attachments = [attachment.text for attachment in XML.parsingFile("attachments", False)]
copyright = XML.parsingFile("copyright")
v = XML.parsingFile("v")
done = False
def publicPosts():
    pass
if __name__ == "__main__":
    done = True
while done:
    publicPosts()
    time.sleep(intervalPost)

Чтобы публиковать запись будем вызвать метод API «wall.post» и передавать параметры получение раньше. Если все сработает правильно будет выводится соответствующее сообщение в консоль.

import vk_api
import time
from modules import XML as moduleXml
XML = moduleXml.XML("settings")
VK = vk_api.VkApi(token=XML.parsingFile("token"))
groupsId = []
groupsShortName = ""
for child in XML.parsingFile("groups", False):
    groupsShortName += child.text + ","
for group in VK.method("groups.getById", {"group_ids": groupsShortName}):
    groupsId.append(group["id"] * -1)
del groupsShortName
textPost = XML.parsingFile("textPost")
intervalPost = int(XML.parsingFile("interval"))
attachments = [attachment.text for attachment in XML.parsingFile("attachments", False)]
copyright = XML.parsingFile("copyright")
v = XML.parsingFile("v")
done = False
def publicPosts():
    for groupId in groupsId:
        for i in range(1, 5):
            result = VK.method("wall.post", {
                "owner_id": groupId,
                "message": textPost,
                "attachments": attachments,
                "copyright": copyright,
                "v": v
            })
            if result["post_id"]:
                print("Good post, id post - " + str(result["post_id"]))
            else:
                print("Error posting")
if __name__ == "__main__":
    done = True
while done:
    publicPosts()
    time. sleep(intervalPost)

Заключение

Вот и все, весь код готов. Скажу Вам сразу же мне — 13 лет. И я хочу рассказать и поделиться тем, что я умею и считаю интересным для других. Так мою прошлую публикацию прочитали 2к+ человек, а 40 человек сохранили в закладки, хотя там и есть, что доработать. Это меня замотивировала, спасибо Вам большое.

Проект на gitHub.

ВНИМАНИЕ: статья создана только в обучающих целях, я не призываю Вас использовать продукт полученный в конце урока для принесения неудобств или собственной выгоды

Dr.Web — инновационные антивирусные технологии. Комплексная защита от интернет-угроз.

Для полноценной работы нашего сайта в вашем браузере требуется поддержка JavaScript.

ДЛЯ КЛИЕНТОВ

  • Активируйте лицензию Dr. Web
  • Техническая поддержка
  • Документация
  • Скачать Dr.Web

Закрыть

  • Назад
  • Дом
  • Контактная поддержка

Библиотека

Моя библиотека

Поиск

Поиск

Профиль Icon_rotate180:hidden»/>

RU

RU CN DE RU ЕС Франция ЭТО Япония PL КЗ UA К

white:hidden»> Закрыть

  • Дом
  • Бизнес
  • интернет-магазин
  • Скидки
  • Скачать
  • Поддерживать
  • Обучение
  • Партнеры
  • Информация
  • Центр борьбы с кибермошенничеством
  • Лицензионный центр
  • Клиенты
  • Антивирусная лаборатория
  • О компании «Доктор Веб»
Оповещения о вирусах
Антивирусные времена
    schema.org/SiteNavigationElement»>
  • Вопрос дня
  • Все выпуски
  • Категории
Коробки новостей
Пресс-центр
  • Контактная информация для прессы
  • пресс-кит
  • Галерея

криптогрупп в российских соцсетях пострадали от ботов, дискредитирующих биткойн – Новости биткойнов

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

Боты заполонили группы Вконтакте комментариями против криптовалюты

За последнюю неделю или около того в группах, посвященных криптовалютам, в контролируемой государством социальной сети России «ВКонтакте» (ВК) наблюдается рост числа комментариев, направленных на дискредитацию криптовалют и связанных с ними технологий, сообщили новостные агентства о криптовалютах Bits.media и РБК Крипто. .

Комментарии отображаются под сообщениями и связанными статьями о криптоактивах. Они все похожи, например: «В крипту копаться дороже, это всегда большие риски», «Кто-то еще говорит о биткойнах?» или «Люди, которые болтают о криптографии, даже не понимают ее».

По словам Никиты Зуборева, старшего аналитика биржевого агрегатора Bestchange.ru, эти боты впервые появились в сообществе его платформы и на официальной странице ВКонтакте 13 февраля. Аккаунты типичны для подобных атак и представляют собой недавно зарегистрированные или украденные неактивные аккаунты. .

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

В пресс-службе

«ВКонтакте» РБК сообщили, что компания «не фиксирует увеличения количества ботов на платформе» и заверили, что ее модераторы «оперативно реагируют на жалобы» на ботов, которые массово размещают одну и ту же информацию.

Зуборев также прокомментировал, что пока сложно установить, на что именно реагируют боты. По его наблюдениям, они игнорируют сообщения, содержащие изображения, но активируются теми, которые содержат такие слова, как «Binance», «биткойн» или «блокчейн». На этой неделе атаки усилились, отмечает аналитик.

Криптоканалы в Telegram не подвержены атакам ботов

Трудно понять смысл и эффективность такой кампании против криптовалют, отметил генеральный директор дефи банковской платформы Индефибанк Сергей Менделеев, так как большая часть русскоязычного криптосообщества не использует эту социальную платформу «по понятным причинам».

Менделеев считает, что кто-то заказал атаки, чтобы потом ссылаться на «большой объем негативных комментариев в самой популярной социальной сети». Эксперт указал, что подобных атак на криптоканалы в Telegram не наблюдалось.

ВКонтакте был основан в 2006 году российским предпринимателем Павлом Дуровым, позже запустившим мессенджер Telegram. В апреле 2014 года Дуров был уволен с поста генерального директора ВКонтакте. Он предположил, что этот шаг был связан с его отказом передать личные данные пользователей российским правоохранительным органам, в том числе членов группы, занимающейся протестами Евромайдана в Украине, и покинул Россию.

В сентябре того же года группа Mail.ru стала единоличным владельцем компании. В декабре 2021 года российский госбанк «Газпромбанк» и страховая компания «Согаз» выкупили 57,3% акций ВК, став держателями ее контрольного пакета. Вконтакте недавно запустил сервис NFT.

Теги в этой истории

анти-биткоин, Атаки, Биткойн, Боты, кампания, Каналы, Крипто, криптоканалы, криптогруппы, Криптовалюты, Криптовалюта, Группы, Сообщения, мессенджер, Никита Зуборев, Павел Дуров, Посты, Россия, русский, Социальные медиа, соц. медиаплатформа, Социальная сеть, Telegram, ВКонтакте, Вконтакте

Как вы думаете, кто стоит за атаками на криптогруппы Вконтакте? Поделитесь своими мыслями по этому вопросу в разделе комментариев ниже.

Любомир Тасев

Любомир Тасев — журналист из технически подкованной Восточной Европы, которому нравится цитата Хитченса: «Быть ​​писателем — это то, чем я являюсь, а не то, что я делаю». Помимо криптографии, блокчейна и финтеха, международная политика и экономика являются двумя другими источниками вдохновения.

Кредиты изображений : Shutterstock, Pixabay, Wiki Commons, Бурдун Илья / Shutterstock.com

Отказ от ответственности : Эта статья предназначена только для информационных целей. Это не прямое предложение или ходатайство о покупке или продаже, а также рекомендация или одобрение каких-либо продуктов, услуг или компаний. Bitcoin.com не предоставляет инвестиционных, налоговых, юридических или бухгалтерских консультаций.