python — Парсер для вк записывает в файл только часть данных
Данный код должен собирать все поcnы в пределах заданного количества «amount = 1000» из группы и записывать их в файл в виде: пост, ветки комментариев к этому посту и тд. При выполнении данного кода из 856 постов в этой группе вк в файл записывается только 311 постов и выдает такую ошибку
Traceback (most recent call last): File «C:\Users\User\PycharmProjects\parser_vk_all_comments\dubl.py», line 167, in comment_writer(all_comments, k) File «C:\Users\User\PycharmProjects\parser_vk_all_comments\dubl.py», line 33, in comment_writer a_pen.writerow([all_comments[i][‘id’], all_comments[i][‘text’], all_comments[i][‘likes’][‘count’], ‘-‘, ‘comment’, KeyError: ‘text’:
Код:
import csv import requests token = 'token' version = 5.131 owner_id = '-174228153' post_id = 0 comment_id = 0 count = 1000 amount = 1000 i = 0 def file_create(): with open('parsing.csv', 'w', encoding='utf-8') as file: a_pen = csv.writer(file) a_pen.writerow(['id', 'text', 'likes', 'reposts', 'type', 'parents_stak', 'owner_id']) # функция записи данных в файл def post_writer(all_post, i): # i индекс поста из списка with open('parsing.csv', 'a', encoding='utf-8') as file: a_pen = csv.writer(file) i = i a_pen.writerow((all_post[i]['id'], all_post[i]['text'], all_post[i]['likes']['count'], all_post[i]['reposts']['count'], 'post', '-', all_post[i]['owner_id'])) def comment_writer(all_comments, i): # получает на вход спиок коментов и индекс комента в списке with open('parsing.csv', 'a', encoding='utf-8') as file: a_pen = csv.writer(file) a_pen.writerow([all_comments[i]['id'], all_comments[i]['text'], all_comments[i]['likes']['count'], '-', 'comment', all_comments[i]['post_id'], all_comments[i]['owner_id']]) def subcomment_writer(all_undercom): # получает на вход список субкоментов и все их записывает в файл with open('parsing. csv', 'a', encoding='utf-8') as file: a_pen = csv.writer(file) t = 0 for subcom in all_undercom: while t < len(all_undercom): a_pen.writerow((all_undercom[t]['id'], all_undercom[t]['text'], all_undercom[t]['likes']['count'], '-', 'subcomment', all_undercom[t]['id'], all_undercom[t]['owner_id'])) t += 1 else: pass # получение всех постов def get_posts(token, owner_id, amount): token = token version = 5.131 owner_id = owner_id count = 100 offset = 0 all_posts = [] while offset < amount: response = requests.get('https://api.vk.com/method/wall.get', params={ 'access_token': token, 'v': version, 'owner_id': owner_id, 'count': count, 'offset': offset }) data = response.
json()['response']['items'] offset += 100 all_posts.extend(data) return all_posts # Получение id текущего поста def get_post_id(all_post, i): for post in all_post: post_id = all_post[i]['id'] return post_id # получение всех коментариев под постом def get_comments(token, owner_id, post_id, amount): token = token version = 5.131 owner_id = owner_id post_id = post_id count = 100 offset = 0 all_comments = [] while offset < amount: response = requests.get('https://api.vk.com/method/wall.getComments', params={ 'access_token': token, 'v': version, 'owner_id': owner_id, 'post_id': post_id, 'need_likes': 1, 'count': count, 'offset': offset }) data = response. json()['response']['items'] offset += 100 all_comments.extend(data) return all_comments # получение id текущего комментария def get_comment_id(all_comments, i): comment_id = None for coment in all_comments: if i < len(all_comments): comment_id = all_comments[i]['id'] else: pass return comment_id # получение ветки подкоментариев def get_vetcom(token, owner_id, post_id, comment_id, amount): token = token version = 5.131 owner_id = owner_id post_id = post_id comment_id = comment_id count = 100 offset = 0 all_comments_vet = [] while offset < amount: response = requests.get('https://api.vk.com/method/wall.getComments', params={ 'access_token': token, 'v': version, 'owner_id': owner_id, 'post_id': post_id, 'need_likes': 1, 'comment_id': comment_id, 'count': count, 'offset': offset }) data = response.
json()['response']['items'] offset += 100 all_comments_vet.extend(data) return all_comments_vet file_create() all_post = get_posts(token, owner_id, amount) # получили список постов print(len(all_post)) all_comments = None all_undercom = None while i < len(all_post): post_writer(all_post, i) post_id = get_post_id(all_post, i) # получили id текущего поста all_comments = get_comments(token, owner_id, post_id, amount) # получили список коментариев под этим постом k = 0 while k < len(all_comments): comment_writer(all_comments, k) comment_id = get_comment_id(all_comments, k) # получили id n-го комментария из списка комментариев print(len(all_comments)) all_undercom = get_vetcom(token, owner_id, post_id, comment_id, amount) # получили список подкоментариев этого коментария print(len(all_undercom)) subcomment_writer(all_undercom) k += 1 i += 1 print(len(all_post)) print(1)
Если оставить только часть которая записывает только посты без комментариев, то записываются все посты:
import csv import requests token = 'token' version = 5. 131 owner_id = '-174228153' post_id = 0 comment_id = 0 count = 1000 amount = 1000 i = 0 def file_create(): with open('parsing1.csv', 'w', encoding='utf-8') as file: a_pen = csv.writer(file) a_pen.writerow(['id', 'text', 'likes', 'reposts', 'type', 'parents_stak', 'owner_id']) # функция записи данных в файл def post_writer(all_post, i): # i индекс поста из списка with open('parsing1.csv', 'a', encoding='utf-8') as file: a_pen = csv.writer(file) i = i a_pen.writerow((all_post[i]['id'], all_post[i]['text'], all_post[i]['likes']['count'], all_post[i]['reposts']['count'], 'post', '-', all_post[i]['owner_id'])) def get_posts(token, owner_id, amount): token = token version = 5.131 owner_id = owner_id count = 100 offset = 0 all_posts = [] while offset < amount: response = requests.get('https://api.vk.com/method/wall.get', params={ 'access_token': token, 'v': version, 'owner_id': owner_id, 'count': count, 'offset': offset }) data = response.
json()['response']['items'] offset += 100 all_posts.extend(data) return all_posts file_create() all_post = get_posts(token, owner_id, amount) # получили список постов print(len(all_post)) while i < len(all_post): post_writer(all_post, i) i += 1
Помогите пожалуйста разобраться в чем проблема
Как создать бот-парсер пабликов VK
Таргетированная реклама — проверенный временем инструмент. Но в случае с VK аудитория многих пабликов — фейки. Чтобы не растрачивать бюджет впустую — создадим бота, который будет анализировать аудиторию паблика. Напомним, что ранее мы уже создавали бота-говорилку для VK — советуем ознакомиться с материалом и более детальным разбором особенностей создания ботов для VK.
*Спойлер: готовый исходный код — в конце статьи.
Какие задачи решает ботДанный бот предназначен для непосредственной оценки потенциала аудитории пабликов VK для рекламных целей. Для этого бот:
Парсерит список участников сообществ.
Вытягивает информацию для оценки со страницы каждого отдельно взятого участника.
Сопоставляет полученную информацию.
Выводит процентные значения.
Предложенным функционалом прикладной потенциал бота не ограничивается и может быть расширен путем «пришивания» к нему новых функций. Но для демонстрации принципа того, как происходит отсеивание «мусорных пабликов», — перечисленного выше более чем достаточно.
Принцип работы ботаПринцип работы бота следующий:
Бот получает сообщение от пользователя с адресом группы.
Парсит аудиторию паблика.
Проверяет каждого пользователя на бан VK.
Проверяет каждого пользователя на наличие фотографии.
Проверяет каждого пользователя на время последнего появления в сети.
Проверяет каждого пользователя на дату регистрации.
Возвращает в ЛС сообщение с процентным соотношением «фейковых» пользователей к общему числу подписчиков.
- Сперва вам нужно получить токен. Важное уточнение — токен дает полный доступ к странице, так что советуем использовать не основной профиль.
- Затем авторизируемся в pythonanywhere.
- Инициируем запуск Bash-консоли.
- Дожидаемся загрузки машины.
- Ждем подтверждения загрузки.
- Патчим машину под VK API, для этого прописываем:
pip3.9 install vk_api
- Открываем блокнот или другой текстовый редактор, вводим:
import vk_api
import requests
from vk_api. longpoll import VkLongPoll, VkEventType
import time
import json
from bs4 import BeautifulSoup
import datetime as DT
token=»ваш токен»
bh = vk_api.VkApi(token = token)
give = bh.get_api()
longpoll = VkLongPoll(bh)
time = time.time()
def blasthack(id, text):
bh.method(‘messages.send’, {‘user_id’ : id, ‘message’ : text, ‘random_id’: 0})
def ras4eti(s):
bs4et=0
bs4etn=0
fs4et=0
fs4etn=0
ls4et=0
ls4etn=0
rs4et=0
rs4etn=0
users=0
timetest=time-2629743
count = requests. get(‘https://api.vk.com/method/groups.getMembers’, params={
‘access_token’:token,
‘v’:5.103,
‘group_id’: s,
‘sort’:’id_desc’,
‘offset’:0,
‘fields’:’last_seen’
}).json()[‘response’][‘count’]
get_offset=count//1000
good_id_list = []
max_offset = get_offset
if max_offset == 0:
max_offset=1
offset = 0
while offset < max_offset:
response = requests.get(‘https://api.vk.com/method/groups.getMembers’, params={
‘access_token’:token,
‘v’:5.103,
‘group_id’: s,
‘sort’:’id_desc’,
‘offset’:offset,
‘fields’:’last_seen’
}). json()[‘response’]
offset += 1
for item in response[‘items’]:
good_id_list.append(item[‘id’])
with open(‘users.txt’, ‘w’) as f:
for item in good_id_list:
f.write(«%s\n» % item)
blasthack(id, ‘Парсинг завершен, приступаю к анализу (может занять много времени)’)
file1 = open(«users.txt», «r»)
while True:
# считываем строку
line = file1.readline()
users=users+1
# прерываем цикл, если строка пустая
if not line:
break
# выводим строку
a=line. strip()
good_id_list = []
response = requests.get(‘https://api.vk.com/method/users.get’, params={
‘access_token’:token,
‘v’:5.103,
‘user_id’: a,
‘fields’:’last_seen,has_photo’
}).json()[‘response’]
aList = json.dumps(response)
x = aList.split(«,»)
cbt=x[2]
if str(cbt) == str(‘ «deactivated»: «deleted»‘):
bs4et=bs4et+1
else:
bs4etn=bs4etn+1
if str(x[1]) != ‘ «has_photo»: 1’:
fs4et=fs4et+1
else:
fs4etn=fs4etn+1
x[2] = x[2][:-1]
if str(x[2]) != ‘ «last_seen»: {«platform»: ‘:
ls4et=ls4et+1
else:
g=str(x[3])
s = g
s=s. replace(‘ «time»: ‘, »)
s=s.replace(‘}’, »)
if int(s)-time > timetest:
ls4et=ls4et+1
else:
ls4etn=ls4etn+1
response = requests.get(‘https://vk.com/foaf.php?id=’+a)
xml = response.text
soup = BeautifulSoup(xml, ‘lxml’)
created = soup.find(‘ya:created’).get(‘dc:date’)
dt = created
dt = dt.replace(«+03:00», «»)
dt = dt.replace(«T», » «)
dt = DT.datetime.strptime(dt, ‘%Y-%m-%d %H:%M:%S’)
dt=dt.timestamp()
dt=int(dt)
if dt-time>94670778:
rs4et=rs4et+1
else:
rs4etn=rs4etn+1
#закрываем файл
file1. close
prob=int(bs4et/users*100)
prof=int(fs4et/users*100)
prol=int(ls4et/users*100)
pror=int(rs4et/users*100)
print (prob)
print (prof)
print (prol)
print (pror)
blasthack(id, ‘Анализ завершен. \nВ паблике: ‘+s+’\nЗабаненных акков: ‘+str(prob)+’% (‘+str(bs4et)+’)\nАкков без фото: ‘+str(prof)+’% (‘+str(fs4et)+’)\nАкков не заходивших в сеть 30+ дней: ‘+str(prol)+’% (‘+str(ls4et)+’)\nАкков зарегистрированных менее 3 лет назад: ‘+str(pror)+’% (‘+str(rs4et)+’)’)
response=0
for event in longpoll.listen():
if event.type == VkEventType.MESSAGE_NEW:
# Чтобы наш бот не слышал и не отвечал на самого себя
if event. to_me:
# Для того чтобы бот читал все с маленьких букв
message = event.text.lower()
# Получаем id пользователя
id = event.user_id
s = message
response=0
try:
response = requests.get(‘https://api.vk.com/method/groups.getMembers’, params={
‘access_token’:token,
‘v’:5.103,
‘group_id’: s
}).json()[‘response’]
except: response != «error»
if response == 0:
blasthack(id, ‘Паблик с таким ID не существует’)
if response != 0:
blasthack(id, ‘Парсим аудиторию паблика: \n’ +s)
ras4eti(s)
- Указываем токен вместо “ваш токен”.
- Сохраняем код как bot.py.
- Грузим скрипт на сервер.
- Инициируем запуск bot.py.
- Тестируем парсер.
Ссылка на скачивание исходного кода
Подводя итогиКак видите, создать собственный парсер для анализа аудитории не сложно — надеемся, он поможет вам в настройке таргетинга и сэкономит ваш бюджет.
vk-url-scraper · PyPI
Библиотека Python для очистки данных, особенно медиа-ссылок, таких как видео и фотографии, с URL-адресов vk.com.
Вы можете использовать его через командную строку или как библиотеку Python, проверьте документацию .
Установка
Вы можете установить самый последний выпуск из pypi через pip install vk-url-scraper
.
Для использования библиотеки вам понадобится действующая комбинация имени пользователя и пароля для vk.com.
Использование командной строки
# запустите это, чтобы узнать больше о параметрах
vk_url_scraper --help
# очистить URL-адрес и получить результат JSON в консоли
vk_url_scraper -username "логин здесь" --password "пароль здесь" --urls https://vk.com/wall12345_6789
# ИЛИ
vk_url_scraper -u "имя пользователя здесь" -p "здесь пароль" --urls https://vk.com/wall12345_6789
# вы также можете иметь несколько URL-адресов
vk_url_scraper -u "логин здесь" -p "пароль здесь" --urls https://vk.com/wall12345_6789 https://vk.com/photo-12345_6789https://vk.com/video12345_6789
# вы также можете передать токен, чтобы избежать постоянной аутентификации
# и, возможно, получение подсказок по капче
# вы можете получить токен из файла bk_config.v2.json, созданного с помощью поиска "access_token"
vk_url_scraper -u "имя пользователя" -p "пароль" -t "сюда идет vktoken" --urls https://vk.
com/wall12345_6789
# сохранить вывод JSON в файл
vk_url_scraper -u "имя пользователя здесь" -p "здесь пароль" --urls https://vk.com/wall12345_6789 > output.json
# загрузите любые фотографии или видео, найденные по этим URL-адресам
# это будет использовать или создать выходную/папку и сбрасывать туда файлы
vk_url_scraper -u "логин здесь" -p "пароль здесь" --скачать --urls https://vk.com/wall12345_6789# или
vk_url_scraper -u "имя пользователя здесь" -p "здесь пароль" -d --urls https://vk.com/wall12345_6789
Использование библиотеки Python
из vk_url_scraper import VkScraper
vks = VkScraper("имя пользователя", "пароль")
# очистить любой URL-адрес "фото"
res = vks.scrape("https://vk.com/photo1_278184324?rev=1")
# очистить любой URL-адрес "стены"
res = vks.scrape("https://vk.com/wall-1_398461")
# очистить любой URL-адрес "видео"
res = vks.scrape("https://vk.com/video-6596301_145810025")
print(res[0]["text"]) # например: -> чтобы получить текст из кода
# Каждая функция очистки* возвращает список dict, например
{
"id": "wall_id",
"текст": "текст в этом посте" ,
"datetime": дата и время сообщения в формате utc,
"вложения": {
# если есть фото, видео, ссылка
"photo": [список URL с максимальным качеством],
"video": [список URL с максимальным качеством],
"link": [список URL-адресов с максимальным качеством],
},
"payload": "исходный ответ JSON преобразован в dict, который вы можете проанализировать для получения дополнительных данных
}
см. [документы] для всех доступных функций.
ТОДО
- очистить ссылки на альбомы
- очистить ссылки профиля
- документов онлайн от сфинкса
Девелопмент
(подробнее на CONTRIBUTING.md).
- установка среды разработки с
pip install -r dev-requirements.txt
илиpipenv install -r dev-requirements.txt
Среда установки - с
pip install -r requirements.txt
илиpipenv install -r requirements.txt
- Для запуска всех проверок до
сделать прогон-проверки
(стиль фиксов) или индивидуально- Для фиксации стиля:
черный .
исорта.
->чешуйка8 .
для проверки ворса - Для проверки типов:
mypy .
- Для тестирования:
pytest .
(pytest -v --color=yes --doctest-modulestests/ vk_url_scraper/
для подробных сведений о пользователях, цветах и тестовых примерах строк документации)
- Для фиксации стиля:
-
make docs
для создания документов shpynx -> при необходимости отредактируйте config.py
Чтобы протестировать интерфейс командной строки, доступный в main .py, вам нужно передать параметр -m
в python следующим образом: python -m vk_url_scraper -u "" -p "" --urls ...
Выпуск новой версии
- редактирование version.py с правильной версией
- запустите
./scripts/release.sh
, чтобы создать тег и нажать, в качестве альтернативы-
git tag vx.y.z
для тега версии -
git push источник vx.yz
-> это запустит рабочий процесс и поместит проект на pypi
-
- перейдите на https://readthedocs.org/, чтобы развернуть новую версию документации (если веб-перехватчик не настроен)
Исправление неудачного выпуска
Если по какой-то причине рабочий процесс выпуска GitHub Actions завершился с ошибкой, которую необходимо исправить, вам придется удалить как тег, так и соответствующий выпуск с GitHub. После того, как вы отправили исправление, удалите тег из локального клона с помощью
git tag -l | тег xargs git -d && git fetch -t
Затем повторите шаги, описанные выше.
Использование — VK SDK Kotlin
См. примеры проектов:
- Самый подробный пример, написанный на Котлине:
- https://github.com/vksdk/vk-sdk-kotlin/tree/master/examples/jvm-kotlin-example
- Минимальный пример без Kotlin в зависимостях:
- https://github.com/vksdk/vk-sdk-kotlin/tree/master/examples/jvm-only-java-example
- Пример минимального мультиплатформенного приложения (одна активность на Android и SwiftUI на iOS):
- https://github.com/vksdk/vk-sdk-kotlin/tree/master/examples/mpp-example
Артефакты
Список всех доступных артефактов:
реализация "com.petersamokhin.vksdk:http-client-jvm-okhttp:$vkSdkVersion" реализация "com.petersamokhin.vksdk:core-jvm:$vkSdkVersion" реализация "com.petersamokhin.vksdk:http-client-common-ktor-jvm:$vkSdkVersion" реализация "com.petersamokhin.vksdk:core-js:$vkSdkVersion" реализация "com.petersamokhin.vksdk:http-client-common-ktor-js:$vkSdkVersion" реализация "com.petersamokhin.vksdk:core-iosX64:$vkSdkVersion" реализация "com.petersamokhin.vksdk:http-client-common-ktor-iosX64:$vkSdkVersion" реализация "com.petersamokhin.vksdk:core-iosArm32:$vkSdkVersion" реализация "com.petersamokhin.vksdk:http-client-common-ktor-iosArm32:$vkSdkVersion" реализация "com.petersamokhin.vksdk:core-iosArm64:$vkSdkVersion" реализация "com.petersamokhin.vksdk:http-client-common-ktor-iosArm64:$vkSdkVersion" реализация "com.petersamokhin.vksdk:core-tvosX64:$vkSdkVersion" реализация "com.petersamokhin.vksdk:http-client-common-ktor-tvosX64:$vkSdkVersion" реализация "com.petersamokhin.vksdk:core-tvosArm64:$vkSdkVersion" реализация "com.petersamokhin.vksdk:http-client-common-ktor-tvosArm64:$vkSdkVersion" реализация "com.
petersamokhin.vksdk:core-watchosX86:$vkSdkVersion" реализация "com.petersamokhin.vksdk:http-client-common-ktor-watchosX86:$vkSdkVersion" реализация "com.petersamokhin.vksdk:core-watchosArm32:$vkSdkVersion" реализация "com.petersamokhin.vksdk:http-client-common-ktor-watchosArm32:$vkSdkVersion" реализация "com.petersamokhin.vksdk:core-watchosArm64:$vkSdkVersion" реализация "com.petersamokhin.vksdk:http-client-common-ktor-watchosArm64:$vkSdkVersion" реализация "com.petersamokhin.vksdk:core-macosX64:$vkSdkVersion" реализация "com.petersamokhin.vksdk:http-client-common-ktor-macosX64:$vkSdkVersion"
Настройки
Настройки Вк
значение vkClientSettings = VkSettings( // Требуется HTTP-клиент httpКлиент = httpКлиент, // По умолчанию [VkApi.DEFAULT_VERSION], 5.122 для 0.0.7 // См.: https://vk.com/dev/versions апиверсия = 5.122, // Параметры по умолчанию пусты defaultParams = paramsOf («язык» на «ru»), // По умолчанию 3. Укажите [VkApi.EXECUTE_MAX_REQUESTS_PER_SECOND_DISABLED], чтобы отключить цикл выполнения очереди maxExecuteRequestsPerSecond = 3, // По умолчанию используется Dispatchers.Default из общего модуля kotlin coroutines // См. пример мультиплатформы и примечание iOS для ktor backgroundDispatcher = Диспетчеры.По умолчанию, json = Json { /* ваша конфигурация */ } )
Инициализация
Этот клиент используется во всех фрагментах в следующих разделах.
val клиент = VkApiClient( // Идентификатор пользователя или сообщества идентификатор = 151083290, // Токен доступа к API ВКонтакте. Должен иметь область действия «офлайн», чтобы не было истечения срока действия. // Подробнее: https://vk.com/dev/access_token токен = "abcdef123456...", // Работа с API сообщений доступна только для Сообществ тип = VkApiClient.Type.Community, // См. предыдущий фрагмент настройки = вкНастройки )
Кроме того, для серверных приложений полезно делать что-то от имени пользователя, но отправлять маркер доступа с клиента небезопасно. Здесь может помочь поток кода авторизации.
// Отсюда: https://vk.com/apps?act=manage // Выберите приложение и получите идентификатор и другую информацию из настроек приложения // Идентификатор приложения, ключ безопасности и т. д. val информация о приложении = информация о приложении ( идентификатор клиента = 123456789, clientSecret = "abcdef12345...", redirectUri = "https://oauth.vk.com/blank.html" ) val client = VkApiClient.fromCode( // Код от клиента код = "abcdef12345...", // Информация о приложении, см. выше приложение = информация о приложении, // См. предыдущие фрагменты; настройки для клиента // Клиент всегда является пользователем для потока кода настройки = вкНастройки )
запросов API
Вы можете повторно использовать запросы следующим образом:
// запрос информации val запрос = client.call("users.get", paramsOf("user_id" до 1))
Синхронный вызов
// Это всегда строка, вы должны разобрать ее сами val ответ: String = request.execute()
Асинхронный вызов
request.enqueue (объект: обратный вызов{ переопределить удовольствие onResult (результат: строка) { // Это всегда строка, вы должны разобрать ее самостоятельно } переопределить удовольствие при ошибке (ошибка: исключение) { println("Произошла ошибка:") ошибка.printStackTrace() } })
Пакетные запросы
Запросы из пакетной очереди выполняются как можно скорее на основе количества запросов в очереди.
Используя это, вы не можете превысить лимит запросов в секунду API ВКонтакте.
Обратный вызов использует JsonElement
, потому что ВК выполняет метод
, возвращающий массив ответов, он анализируется и нужный элемент возвращается в обратный вызов.
Может быть false
в случае ошибки.
Передайте обратный вызов:
client.call (запрос, пакет = истина, объект: обратный вызов{ переопределить удовольствие onResult (результат: строка) { // Это всегда JsonElement, вы должны разобрать его самостоятельно } переопределить удовольствие при ошибке (ошибка: исключение) { println("Произошла ошибка:") ошибка. printStackTrace() } })
Или используйте два обратных вызова
client.call (запрос, пакет = истина, onResult = {результат: JsonElement -> // Это всегда JsonElement, вы должны разобрать его самостоятельно }, onError = { ошибка: исключение -> println("Произошла ошибка:") ошибка.printStackTrace() })
Также можно передавать параметры не только объекта запроса
client.call("users.get", paramsOf("user_id" до 1), batch = true, /* обратные вызовы */)
Делайте столько запросов, сколько хотите
для (i от 0 до 500) { client.call("users.get", paramsOf("user_id" до 1), batch = true, /* обратные вызовы */) // без задержки() ! }
Пройдите их все за один раз:
val запросы: List= listOf(1, 2, 3, 4, 5) .map {userId -> client.call («users.get», paramsOf («user_id» в userId)) } .map { запрос -> BatchRequestItem (запрос, объект: Callback { /* */ }) } client. call(запросы)
Потоков для запросов
Весь функционал на основе Flows
доступен от делегата:
val потоки: VkApiClientFlows = client.flows()
В остальном то же самое:
клиент.потоки() .call(request, batch = true) // или укажите имя метода и параметры .onEach { результат: JsonElement -> /* сделать что-то */ } .catch { e -> /* сделать что-нибудь */ } .flowOn(Диспетчеры.IO) .launchIn(жизненный цикл)
Отправка сообщений
Используйте DSL:
client.sendMesage { одноранговый идентификатор = 12345678901 message = "Привет, мир!" вложение = "фото1234_5678,фото1234_1234" }.выполнять()
Или используйте конструктор:
значение сообщение = Сообщение() .peerId(12345678901) .text("Привет, мир!") // Затем отправить val запрос = client.send(сообщение) // или еще таким образом val запрос = message.sendFrom(клиент) // Не забывайте об этом! request.execute() // или используйте потоки, обратные вызовы и все, что хотите
Клавиатура
Используйте DSL:
client.sendMessage { одноранговый идентификатор = 12345678901 message = "Привет, мир!" клавиатура = клавиатура(oneTime = true) { // или `inlineKeyboard` для встроенного ряд { primaryButton("Синяя таблетка") { полезная нагрузка = "{}" // и т. д. } отрицательнаяКнопка("Красная таблетка") } } }.выполнять()
Вложения
Все функции, необходимые для загрузки, доступны от делегата:
значение загрузчика: VkApiUploader = client.uploader()
Просто прикрепите изображение:
значение peerId = 12345678901 val imageAttachmentString = client.uploader().uploadPhotoForMessage( одноранговый идентификатор, // или FileOnDisk(path = "/Users/you/Documents/img.png") // или массив байтов URL = "https://example.com/image.png" ) // imageAttachmentString что-то вроде 'photo987654321_1234' client.sendMessage { peerId = необходимыйPeerId вложение = imageAttachmentString }.выполнять()
Прикрепите все, что хотите, например звуковое сообщение:
val необходимыйPeerId = 12345678901 val attachmentType = "аудио_сообщение" // В ВК процесс загрузки вложений скучный // и полностью покрывается этим методом, // но ответы динамические и не могут быть сериализованы за один раз для всех случаев // См.: https://vk.com/dev/upload_files val docAttachmentString = client.uploader().uploadContent( "docs.getMessagesUploadServer", // Первый шаг: метод получения `upload_url` "docs.save", // Последний шаг: сохранить вложение на сервере ВКонтакте (можете ли вы, ребята из ВК, сделать это под капотом?) params = paramsOf («тип» для типа приложения, «peer_id» для необходимого идентификатора узла), элементы = список( ЗагружаемыйКонтент.Файл( имя_поля = "файл", // Укажите эти параметры, но не беспокойтесь об их значениях; // но без них вы получите ответ об ошибке.fileName = "не имеет значения, но VK API не стабилен; имя_файла не должно быть пустым", mediaType = "тоже не имеет значения", file = FileOnDisk("/Users/petersamokhin/Desktop/test.mp3") ) ) ).let { ответ: строка -> // Запрос синхронный. Вы должны проанализировать ответ самостоятельно получитьПриложение (оно, тип прикрепления) } client.sendMessage { peerId = необходимыйPeerId // или docAttachmentString, в зависимости от вашей реализации метода retrieveAttachmentd вложение = "doc${docAttachmentString}" }.выполнять()
Типы предметов
:
Массив байт :
значение Массив байтов: Массив байтов = извлечение байтовоткуда-то() val bytesItem: UploadableContent = UploadableContent.Bytes( имя_поля = "файл", имя_файла = "что-то.txt", mediaType = "текст/обычный", байты = массив байтов )
Файл из файловой системы (доступно только для JVM, darwin и JS):
val fileItem: UploadableContent = UploadableContent.File( имя_поля = "файл", имя_файла = "test.mp3", mediaType = "аудио/мпег", file = FileOnDisk("/Users/petersamokhin/Desktop/test.mp3") )
Что-то по URL :
значение urlItem: UploadableContent = UploadableContent.Url( имя_поля = "файл", имя_файла = "изображение.png", mediaType = "изображение/png", URL = "https://example.com/image.png" )
Реагировать на события
Используйте API длинных опросов ботов.
Начать прослушивание событий:
val настройки = VkBotsLongPollApi.Settings( ожидание = 25, // значение по умолчанию; рекомендовано ВК maxFails = 5 // Используйте VkBotsLongPollApi.Settings.IGNORE_FAILS, чтобы игнорировать все ошибки ) // Все параметры являются необязательными; не забывайте о примечании выше client.startLongPolling (перезапуск = ложь, настройки = настройки)
Слушайте новые сообщения:
client.onMessage { событие: MessageNew -> если (event.message.isFromChat()) { client.sendMessage { peerId = событие.сообщение.peerId message = "Привет, чат" }.выполнять() } еще { client.sendMessage { peerId = событие.сообщение.peerId message = "Извините, я игнорирую личные разговоры." }.выполнять() } }
Слушайте все типы событий:
client.onEachEvent {событие: JsonElement -> // Вы должны разобрать событие }
И, конечно же, Flow
пример:
клиент.потоки().onMessage() .flatMapLatest { если (it.message.isFromChat()) { client.flows().sendMessage { peerId = it.message.peerId message = "Привет, чат" } // не нужно выполнять и т. д., потому что поток переключается } еще { client.flows().sendMessage { peerId = it.message.peerId message = "Извините, я игнорирую личные разговоры." } // не нужно выполнять и т.