YariKartoshe4ka / vk-messages-saver

Утилита для сохранения переписок ВКонтакте
GNU General Public License v3.0
18 stars 0 forks source link

Flood control #19

Open h31p opened 3 weeks ago

h31p commented 3 weeks ago

vkms -vv -i xxxxxxxxx dump -a -t 1 --export-json

2024-10-03 09:47:15,086 | INFO | vkms.main | MainThread |: VKMS 1.0.3.dev7+gf299608 started
2024-10-03 09:47:49,109 | ERROR | vk.session | Thread-_0 |: Handle API error: 9. Flood control. request_params = {'method': 'messages.getHistory', 'oauth': '1', 'v': '5.131', 'offset': '800', 'count': '200', 'peer_id': 'xxxxxxxxx', 'rev': '1'}
2024-10-03 09:47:50,305 | ERROR | vk.session | Thread-_0 |: Handle API error: 9. Flood control. request_params = {'method': 'messages.getHistory', 'oauth': '1', 'v': '5.131', 'offset': '2400', 'count': '200', 'peer_id': 'xxxxxxxxx', 'rev': '1'}
2024-10-03 09:47:57,067 | ERROR | vkms.actions | MainThread |: Downloading peer xxxxxxxxx failed: 9. Flood control. request_params = {'method': 'messages.getHistory', 'oauth': '1', 'v': '5.131', 'offset': '800', 'count': '200', 'peer_id': '56834073', 'rev': '1'}
2024-10-03 09:47:57,067 | INFO | vkms.main | MainThread |: VKMS completed

как бороться? пробовал выжидать время - даже спустя несколько часов с первого же раза Flood control

[       4096]  .
└── [       4096]  vkms-result
    ├── [       4096]  .json
    ├── [        916]  logs.txt
    └── [       4096]  .sqlite
        └── [      16384]  xxxxxxxxx.sqlite
YariKartoshe4ka commented 1 week ago

Сейчас за 5 минут накостылил такое решение: вставлять мусорные запросы между нужными. Выглядит ущербно и работает гораздо медленнее (только в 1 потоке). Если есть идеи, буду рад.

diff --git a/vkms/actions.py b/vkms/actions.py
index 61b5f81..c5d6166 100644
--- a/vkms/actions.py
+++ b/vkms/actions.py
@@ -1,7 +1,9 @@
 import logging
 from time import sleep
+from random import choice

 import vk
+from vk.api import APIRequest
 from sqlalchemy import func
 from vk.exceptions import VkAPIError

@@ -30,10 +32,27 @@ def dump(out_dir, include, exclude, token, nthreads, max_msgs, append, export_js
     """
     # Получаем объект для работы с VK API
     class API(vk.API):
+        def send(self, request, *args, flood=False, **kwargs):
+            if not flood:
+                methods = [
+                    'users.get',
+                    'wall.get',
+                    'docs.get',
+                    'friends.get',
+                    'pages.get',
+                    'account.getInfo'
+                ]
+                self.send(APIRequest(choice(methods), request.method_params), flood=True)
+
+            return super().send(request, *args, **kwargs)
+
         def on_api_error_6(self, request):
             sleep(1)
             return self.send(request)

+        def on_api_error_100(self, request):
+            return
+
         def get_captcha_key(self, request):
             return input(f'Captcha needed ({request.api_error.captcha_img}): ')
YariKartoshe4ka commented 1 week ago

Выяснил экспериментально, что ошибка Flood Control привязывается к определнному приложению, т.е. чем больше токенов от разных приложений используется, тем меньше шанс ее возникновения. Пробовал тестить с 8 разными токенами в одном потоке, работает несколько циклов и все равно выдает ошибку. Нужно как-нибудь нафаззить дополнительных cleint_id оффициальных приложений с правами messages. Я нашел только VK Admin, VK Admin (iOS), Маруся, Звонки ВКонтакте, vk.com, VK for Android, VK for iPhone, Kate Mobile

YariKartoshe4ka commented 1 week ago

Почему-то я все еще могу выгружать сообщения через execute (без ошиюок в 4 потока). Если мне не изменяет память, использование методов API через execute тоже подсчитывалось. Как будет время попробую переписать дамп на API.execute