Парсинг плэйлистов vk
Вопрос следующий, мне нужно спарсить данные по ссылке: https://vk.com/music/playlist/304750709_375
А именно данные из класса audioPlaylist__genres
Если перейти не авторизованным на сайт, то можно увидеть что класс содержит следующие данные: “5M прослушиваний · обновлён сегодня в 13:43”
Если начать парсить через BeautifulSoup
import requests
from bs4 import BeautifulSoup as bs
URL = 'https://vk.com/music/playlist/304750709_375'
req = requests.get(URL)
soup = bs(req.text, 'html.parser')
listen = soup.find("div", class_="audioPlaylist__genres")
print(listen)
То результат будет следующим:
<div class="audioPlaylist__genres">4.9M прослушиваний · обновлён сегодня в 13:43</div>
Без парсинга результат 5М, а после парсинга 4.9М. Такая ситуация случается, как я понял, из за того что в первом случае число округляется.
Если авторизоваться в VK и посмотреть ту же страницу, то можно увидеть следующий результат (https://vk.com/audios26845044?block=my_playlists§ion=all&z=audio_playlist304750709_375): “4 954 179 прослушиваний обновлён сегодня в 15:43”
Отсюда следующие вопросы: Получается, что на страницу передается полное число (4 954 179) но уже на ней преобразуется в вид 4.9М? Если, все так, то как я могу спарсить именно полное число (4 954 179), будучи не авторизованным на сайте
Ответы (1 шт):
Без парсинга результат 5М, а после парсинга 4.9М. Такая ситуация случается, как я понял, из за того что в первом случае число округляется.
Нет, такая ситуация получается, потому что BS видит мобильную версию сайта. В мобильной версии сайта 4.9М, в десктопной 5М.
Чтобы таких казусов больше не случалось, передавай правильный User-Agent в headers:
import requests
from bs4 import BeautifulSoup as bs
URL = 'https://vk.com/music/playlist/304750709_375'
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:107.0) Gecko/20100101 Firefox/107.0'}
req = requests.get(URL, headers=headers)
soup = bs(req.text, 'lxml')
listen = soup.find_all("div", class_="AudioPlaylistSnippet__info")
print(listen)
Вывод:
[<div class="AudioPlaylistSnippet__info">
970 аудиозаписей
</div>, <div class="AudioPlaylistSnippet__info">
5M прослушиваний · обновлён вчера в 13:43
</div>]
Получается, что на страницу передается полное число (4 954 179) но уже на ней преобразуется в вид 4.9М?
Нет, получается, что без авторизации с страницы https://vk.com/audios26845044?block=my_playlists§ion=all&z=audio_playlist304750709_375 перенаправляет на https://vk.com/music/playlist/304750709_375
На результирующей странице, после редиректа, полное число не передаётся, php возвращает именно 5M, округление идёт на стороне backend, которое ты никак не увидишь.
Полное же число можно найти в POST запросе, который делается для формирования всплывающего окна.
как я могу спарсить именно полное число (4 954 179), будучи не авторизованным на сайте
К счастью, POST запрос из первой ссылки прекрасно работает без авторизации:
import requests
import re
url = r'https://vk.com/al_audio.php'
params = {'act': 'load_section'}
headers = {'X-Requested-With': 'XMLHttpRequest'}
data = {
'al': 1,
'owner_id': 304750709,
'playlist_id': 375,
'type': 'playlist'
}
r = requests.post(url, data, headers=headers, params=params)
print(int(re.search(r'(?<="listens":")\d+', r.text).group(0)))
Вывод:
4958352
Тут r (response) можно парсить через BeautifulSoup, можно преобразить через json.loads, но если кроме числа прослушиваний ничего не надо, то достаточно и регулярные-выражения, они отрабатывают на 5% быстрее на единичном запросе.