@doktorfish0078

Как сделать так чтобы бот вк на python делал скрин сайта, обрезал его и отправлял фото в беседу не сохраняя его?

Моя цель отправлять фото не сохраняя его, я requests'ом захожу на сайт, делаю там скрин с помощью selenium,потом обрезаю его до нужных размеров с помощью Pillow(PIL). После чего пытаюсь послать Post-запрос к вк, передавая байтовое представление этого скрина,которое получаю с помощью функции tobytes библиотеки PIL, которая доступна для класса Image, но в Post-запросе,который посылаю вк получаю хэш и сервер,но лист с photo пустой.
Я проделал аналогичный трюк, но не со скрином,а просто с ссылкой на картинку в интернете и отправляя в Post запрос request.get(url).content оно работает и запрос возвращает всё что нужно
Следовательно я допускаю ошибку в том, что не то передаю в запрос.
Читал документацию вк апи (https://vk.com/dev/upload_files?f=2.%20Загрузка%20...), но не смог благодаря ей лучше разобраться
region.tobytes возвращает байтную картинку,но у неё первые процентов 70 кода как буд-то битые,ибо там \x00\x00\x00\x00\x00\ и только под конец есть уже какие-то значимые байты.
Помогите реализовать эту функцию пожалуйста,сижу с этим уже недели 2...
def get_schedule_bus():
    now = datetime.datetime.now()
    URL = "https://igis.ru/gortrans/bus/izh/29"
    driver = webdriver.PhantomJS()
    driver.set_window_size(1600, 2070)
    driver.get(URL)
    elem = driver.find_element_by_class_name("table-st1")  # находим нужный нам элемент
    screen = driver.get_screenshot_as_png()  # получаем байтовое представление скриншота
    rect = elem.rect  # {'height': 1041, 'width': 722, 'x': 562, 'y': 689} получаем расположение нужного элемента
    box = (
    rect['x'], rect['y'], rect['x'] + rect['width'], rect['y'] + rect['height'])  # делаем коробку для обреза фото
    im = Image.open(BytesIO(screen))  # открывает скрин
    region = im.crop(box)  # вырезаем
    driver.quit()
    return region.tobytes()


print(get_schedule_bus())
image_data = get_schedule_bus()
upload_url = vk_api.photos.getMessagesUploadServer(group_id=group_id)['upload_url'] #получаем url от вк куда можно будет залить фото
image_name = "kek{}.png".format(random.randint(0, 10)) # делаем рандомное имя фотки
r = requests.post(upload_url, files={'photo': (image_name, image_data) }).json() # посылаем пост запрос вк
print(r)
d = {}
d['server'] = r['server']
d['photo'] = r['photo']
d['hash'] = r['hash']
d['group_id'] = group_id

photo = vk_api.photos.saveMessagesPhoto(**d)[0] # сохраняем на их сервере,как гласит документация

attachment = "photo{}_{}_{}".format(photo['owner_id'], photo['id'], photo['access_key'])
vk_session.method("messages.send",
                    {"chat_id": 2, "message": "", "attachment": attachment, "random_id": random.randint(0, 2048)})

5f60f88bb177a719721951.png
  • Вопрос задан
  • 248 просмотров
Решения вопроса 1
SoreMix
@SoreMix Куратор тега Python
yellow
Как-то странно вы фото отправляете.
{'photo': (image_name, image_data) }

Зачем передавать кортеж в поле photo, если туда нужно передать только байты изображения, которые в обычном виде, при загрузке с файла, выглядят так
{'photo': open(image_name, 'rb') }

В вашем же случае, я так понимаю, должно быть
{'photo': image_data }

Ну и не думаю, что tobytes() подходит для этого. Не занимаюсь обработкой изображений, но я бы сделал примерно так
b = BytesIO()
region.save(b, 'jpeg')
return b.getvalue()
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы