0

Вопрос следующий, мне нужно спарсить данные по ссылке: 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>

Без парсинга результат , а после парсинга 4.9М. Такая ситуация случается, как я понял, из за того что в первом случае число округляется.

Если авторизоваться в VK и посмотреть ту же страницу, то можно увидеть следующий результат (https://vk.com/audios26845044?block=my_playlists&section=all&z=audio_playlist304750709_375): “4 954 179 прослушиваний обновлён сегодня в 15:43”

Отсюда следующие вопросы: Получается, что на страницу передается полное число (4 954 179) но уже на ней преобразуется в вид 4.9М? Если, все так, то как я могу спарсить именно полное число (4 954 179), будучи не авторизованным на сайте

DiMithras
  • 2,658

1 Answers1

0

Без парсинга результат 5М, а после парсинга 4.9М. Такая ситуация случается, как я понял, из за того что в первом случае число округляется.

Нет, такая ситуация получается, потому что BS видит мобильную версию сайта. В мобильной версии сайта 4.9М, в десктопной .

Чтобы таких казусов больше не случалось, передавай правильный 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&section=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% быстрее на единичном запросе.

DiMithras
  • 2,658