Хочу спарсить всю стенку одной группы ВКонтакте. Там много записей.
Узнал, что есть метод wall.get, но его можно вызвать всего лишь 2500 раз в сутки. Этого недостаточно.
Потом узнал про то, что с мобильной версии при прокрутке страницы вниз выполняется такой запрос:
POST https://m.vk.com/clubXYZ?offset=35&own=1
Попробовал через requests - работает. Убрал own=1 - работает.
Также узнал, что ВКонтакте грузит всего 10 постов.
Т.е. если у группы 70'000 постов, то придется сделать 7'000 запросов. Каждый запрос выполняется за 0.2 c -> 23 минуты (а таких групп очень много)
Решил использовать потоки - не помогло, потоки с proxy - не помогло, асинхронные запросы - тоже.
Пробовал асинхронные запросы с прокси, но там костыль на костыле и все равно ничего не работает.
Что можно предпринять для того, чтобы ВКонтакте не банил мои запросы?
И как правильно использовать прокси, если это нужно?
Код
import random
import asyncio
import aiohttp
import aiohttp_socks
from aiohttp import ClientSession
from aiohttp_socks import SocksConnector
import pickle
storage = []
proxies = ['46.4.96.137:1080', '134.0.116.219:1080', '207.154.231.212:1080', '207.154.231.213:1080', '138.68.161.60:1080', '82.196.11.105:1080', '178.62.193.19:1080', '188.226.141.127:1080', '207.154.231.211:1080', '207.154.231.216:1080', '88.198.50.103:1080', '188.226.141.61:1080', '188.226.141.211:1080', '176.9.119.170:1080', '207.154.231.217:1080', '138.68.161.14:1080', '138.68.165.154:1080', '176.9.75.42:1080', '95.85.36.236:1080', '138.68.173.29:1080', '139.59.169.246:1080']
async def fetch(url, i):
l = 1
while l < 10000:
await asyncio.sleep(random.randint(0, 10))
proxy = random.choice(proxies)
# print(proxy)
try:
async with ClientSession(connector=SocksConnector.from_url('socks5://' + proxy)) as session:
async with session.post(url, data={'offset': i}, proxy='http://' + random.choice(proxies)) as response:
s = await response.read()
l = len(s)
print(l)
except aiohttp.client_exceptions.ServerDisconnectedError:
await asyncio.sleep(3)
except aiohttp_socks.proxy.errors.ProxyError:
await asyncio.sleep(3)
storage.append(s)
return s
async def bound_fetch(sem, url, i):
# Getter function with semaphore.
async with sem:
await fetch(url, i)
async def run(r):
url = 'https://m.vk.com/sketch.books'
tasks = []
# create instance of Semaphore
sem = asyncio.Semaphore(1000)
# Create client session that will ensure we dont open new connection
# per each request.
for i in range(0, r + 1, 10):
# pass Semaphore and session to every GET request
task = asyncio.ensure_future(bound_fetch(sem, url, i))
tasks.append(task)
responses = asyncio.gather(*tasks)
await responses
number = 70610
loop = asyncio.get_event_loop()
future = asyncio.ensure_future(run(number))
loop.run_until_complete(future)
print(len(storage))
with open('sketch_books_2.vk', 'wb') as f:
pickle.dump(storage, f)