HTTPS запрос к серверам VK для загрузки видео

Пишу код для загрузки видео из VK без использования VK API. Задача стоит следующая: брать ссылку на видео, далее отправить запрос по этому URL и получить в ответ страницу с просмотром этого видео. То есть симулировать запрос от реального браузера.

Для этого я попробовал скопировать все header'ы из запроса реального браузера следующим образом:

    req, err := http.NewRequest("GET", URL, nil)

    req.Header.Set("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 YaBrowser/24.7.0.0 Safari/537.36")
    req.Header.Set("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7")
    req.Header.Set("Accept-Encoding", "gzip, deflate, br, zstd")
    req.Header.Set("Accept-Language", "ru,en;q=0.9")
    req.Header.Set("Cache-Control", "max-age=0")

    req.Header.Set("Sec-Ch-Ua", "\"Not/A)Brand\";v=\"8\", \"Chromium\";v=\"126\", \"YaBrowser\";v=\"24.7\", \"Yowser\";v=\"2.5\"")
    req.Header.Set("Sec-Ch-Ua-Mobile", "?0")
    req.Header.Set("Sec-Ch-Ua-Platform", "\"macOS\"")
    req.Header.Set("Sec-Fetch-Dest", "document")
    req.Header.Set("Sec-Fetch-Mode", "navigate")
    req.Header.Set("Sec-Fetch-Site", "same-origin")

    req.Header.Set("Upgrade-Insecure-Requests", "1")

    req.Header.Set("Priority", "u=0, I")

В ответ ожидал увидеть страницу с видео для дальнейшей работы, но фактически пришла страница, в которой мне предлагают обновить/установить свежую версию браузера. Пример полученного ответа на Pastebin: URL. визуальное отображение страницы

Вопрос в следующем: как я могу эмулировать запрос от «современного» браузера в Go?

Полный код выглядит следующим образом:

const URL = "https://m.vk.com/video-85466065_456241727"

req, err := http.NewRequest("GET", URL, nil)

req.Header.Set("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 YaBrowser/24.7.0.0 Safari/537.36")
    req.Header.Set("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7")
req.Header.Set("Accept-Encoding", "gzip, deflate, br, zstd")
req.Header.Set("Accept-Language", "ru,en;q=0.9")
req.Header.Set("Cache-Control", "max-age=0")

req.Header.Set("Sec-Ch-Ua", "\"Not/A)Brand\";v=\"8\", \"Chromium\";v=\"126\", \"YaBrowser\";v=\"24.7\", \"Yowser\";v=\"2.5\"")
req.Header.Set("Sec-Ch-Ua-Mobile", "?0")
req.Header.Set("Sec-Ch-Ua-Platform", "\"macOS\"")
req.Header.Set("Sec-Fetch-Dest", "document")
req.Header.Set("Sec-Fetch-Mode", "navigate")
req.Header.Set("Sec-Fetch-Site", "same-origin")

req.Header.Set("Upgrade-Insecure-Requests", "1")

req.Header.Set("Priority", "u=0, i")

client := &http.Client{}

res, err := client.Do(req)


Ответы (1 шт):

Автор решения: Pak Uula

Сдаётся мне, вы получаете правильный ответ от сервера. Браузеры тоже получают его, но выполняют скрипт на JS и перезагружают страницу.

Пруф: скриншот из хрома с отключенным JS введите сюда описание изображения

ИМХО, дело вот в чём. Сервер возвращает вот какой набор куков:

remixlang=0; Path=/; Domain=vk.com; Expires=Sat, 20 Sep 2025 22:04:34 GMT; Secure; SameSite=None
remixstlid=9078596624758655055_ZqB9FcuPZghch6BGgDDoHd6B6dWFHp8zzggYkZA9Z4c; Path=/; Domain=vk.com; Expires=Sun, 21 Sep 2025 10:30:22 GMT; Secure; SameSite=None
remixstid=2019772071_3Tf1dSfwaoxqIPj5Cp2cBYNVL3TxXfC9sHqzoRmsRws; Path=/; Domain=vk.com; Expires=Wed, 24 Sep 2025 19:51:47 GMT; Secure; SameSite=None
remixua=15%7C612%7C171%7C3990382815; Path=/; Domain=vk.com; Expires=Wed, 17 Sep 2025 21:01:56 GMT; Secure; SameSite=None
remixff=0; Path=/; Domain=vk.com; Expires=Tue, 01 Oct 2024 10:30:22 GMT; Secure; SameSite=None
remixua=15%7C612%7C171%7C3990382815; Path=/; Domain=vk.com; Expires=Wed, 24 Sep 2025 21:52:38 GMT; Secure; SameSite=None

Но браузер посылает вот какие куки (значения куков не совпадают, так как одни получены в программе, а другие из браузера - сравнивайте набор имён):

remixlang=0; 
remixua=43%7C-1%7C214%7C2996390830;
remixstlid=9063256236099454727_RxskMlmfWzownbJe8AmH8YjmlSPWFAlQwzMC43sIbpD;
remixstid=359988006_2z3dEIQUE5D2Ea0lRSz5SqCIS4JgGf2rqQIhQKJLkIo;
remixff=0;
remixmdevice=2560/1440/1/!!-!!!!!!!!/1302

Браузер получает куку remixmdevice не из заголовка Set-Cookie, а из скрипта в странице. Без этой куки сервер выдаёт странцу "Плохой браузер", а с ней - нормальную страницу

Я попробовал руками добавить эту куку, и оно таки сработало. Вот мой набор заголовков:

    req.Header.Set("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7")
    req.Header.Set("Accept-Encoding", "gzip, deflate, br, zstd")
    req.Header.Set("Accept-Language", "ru-RU,ru;q=0.9,en-US;q=0.8,en;q=0.7,ko-KR;q=0.6")
    req.Header.Set("Cache-Control", "no-cache")

    // req.Header.Set("Cookie", `remixlang=0; remixua=43%7C-1%7C214%7C2996390830; remixstlid=9063256236099454727_RxskMlmfWzownbJe8AmH8YjmlSPWFAlQwzMC43sIbpD; remixstid=359988006_2z3dEIQUE5D2Ea0lRSz5SqCIS4JgGf2rqQIhQKJLkIo; remixff=0; remixmdevice=2560/1440/1/!!-!!!!!!!!/1302`)

    req.Header.Set("DNT", "1")
    req.Header.Set("Pragma", "no-cache")
    req.Header.Set("Priority", "u=0, i")
    req.Header.Set("Sec-Ch-Ua", `"Chromium";v="128", "Not;A=Brand";v="24", "Google Chrome";v="128"`)
    req.Header.Set("Sec-Ch-Ua-Mobile", "?0")
    req.Header.Set("Sec-Ch-Ua-Platform", `"Android"`)
    req.Header.Set("Sec-Fetch-Dest", "document")
    req.Header.Set("Sec-Fetch-Mode", "navigate")
    req.Header.Set("Sec-Fetch-Site", "same-origin")
    req.Header.Set("Upgrade-Insecure-Requests", "1")
    req.Header.Set("User-Agent", "Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.6668.54 Mobile Safari/537.36")

    req.AddCookie(&http.Cookie{Name: "remixmdevice", Value: "2560/1440/1/!!-!!!!!!!!/1302"})

Я не знаю, как формировать эту куку в динамике. Но пока работает.

PS. По-взрослому, конечно, стоит использовать Selenium, но это такая шайтан-арба...

→ Ссылка