Tengo un código que intenta extraer todas las cosas html dentro del contenedor de la lista de pistas, que debería tener 88 canciones. La información definitivamente está allí (imprimí la sopa para verificar), por lo que no estoy seguro de por qué todo se pierde después de los primeros 30 react-contextmenu-wrapper.

from bs4 import BeautifulSoup
from urllib.request import urlopen
import re


spotify = 'https://open.spotify.com/playlist/3vSFv2hZICtgyBYYK6zqrP'
html = urlopen(spotify)
soup = BeautifulSoup(html, "html5lib")

main = soup.find(class_ = 'tracklist-container')
print(main)

Gracias por la ayuda. La salida actual de la impresión es la siguiente:

                  1.
              </div></div><div class="tracklist-col name"><div class="top-align track-name-wrapper"><span class="track-name" dir="auto">Move On - Teen Daze Remix</span><span class="artists-albums"><a href="/artist/3HrczLBDJXJu6dJWEMbKHa" tabindex="-1"><span dir="auto">Garden City Movement</span></a>     • <a href="/album/4p8FxnuYzykCcN7xbjA9jq" tabindex="-1"><span dir="auto">Entertainment</span></a></span></div></div><div class="tracklist-col explicit"></div><div class="tracklist-col duration"><div class="top-align"><span class="total-duration">5:11</span><span class="preview-duration">0:30</span></div></div><div class="progress-bar-outer"><div class="progress-bar"></div></div></li><li class="tracklist-row js-track-row tracklist-row--track track-has-preview" data-position="2" role="button" tabindex="0"><div class="tracklist-col position-outer"><div class="play-pause top-align"><svg aria-label="Play" class="svg-play" role="button"><use xlink:href="#icon-play" xmlns:xlink="http://www.w3.org/1999/xlink"></use></svg><svg aria-label="Pause" class="svg-pause" role="button"><use xlink:href="#icon-pause" xmlns:xlink="http://www.w3.org/1999/xlink"></use></svg></div><div class="tracklist-col__track-number position top-align">
                  2.
              </div></div><div class="tracklist-col name"><div class="top-align track-name-wrapper"><span class="track-name" dir="auto">Flicker</span><span class="artists-albums"><a href="/artist/4qpWUfUAeI34HzvCORn1ze" tabindex="-1"><span dir="auto">Forhill</span></a>     • <a href="/album/0gfz1Tbst40swwL357cRqG" tabindex="-1"><span dir="auto">Flicker</span></a></span></div></div><div class="tracklist-col explicit"></div><div class="tracklist-col duration"><div class="top-align"><span class="total-duration">3:45</span><span class="preview-duration">0:30</span></div></div><div class="progress-bar-outer"><div class="progress-bar"></div></div></li><li class="tracklist-row js-track-row tracklist-row--track track-has-preview" data-position="3" role="button" tabindex="0"><div class="tracklist-col position-outer"><div class="play-pause top-align"><svg aria-label="Play" class="svg-play" role="button"><use xlink:href="#icon-play" xmlns:xlink="http://www.w3.org/1999/xlink"></use></svg><svg aria-label="Pause" class="svg-pause" role="button"><use xlink:href="#icon-pause" xmlns:xlink="http://www.w3.org/1999/xlink"></use></svg></div><div class="tracklist-col__track-number position top-align">

...

                  30.
              </div></div><div class="tracklist-col name"><div class="top-align track-name-wrapper"><span class="track-name" dir="auto">Trapdoor</span><span class="artists-albums"><a href="/artist/3nqTFzjmi1LLM6pn0TRMv8" tabindex="-1"><span dir="auto">Eagle Eyed Tiger</span></a>     • <a href="/album/48Q8Jgk1x4wiHWecV4nlz6" tabindex="-1"><span dir="auto">Future or Past</span></a></span></div></div><div class="tracklist-col explicit"></div><div class="tracklist-col duration"><div class="top-align"><span class="total-duration">4:14</span><span class="preview-duration">0:30</span></div></div><div class="progress-bar-outer"><div class="progress-bar"></div></div></li></ol><button class="link js-action-button" data-track-type="view-all-button">View all on Spotify</button></div>

La última entrada debería ser la 88. Parece que mis resultados de búsqueda se truncaron.

1
Tangerine Dream 6 oct. 2019 a las 00:13

3 respuestas

La mejor respuesta

Todo está allí en la respuesta solo dentro de una etiqueta script .

Puede ver el inicio del objeto javascript relevante aquí:

enter image description here

Regexearía la cadena requerida y analizaría con la biblioteca json.


Py:

import requests, re, json

r = s.get('https://open.spotify.com/playlist/3vSFv2hZICtgyBYYK6zqrP')
p = re.compile(r'Spotify\.Entity = (.*?);')
data = json.loads(p.findall(r.text)[0])
print(len(data['tracks']['items']))
0
QHarr 6 oct. 2019 a las 05:10

Es porque lo estás haciendo

main = soup.find(class_ = 'tracklist-container')

La clase "tracklist-container" solo contiene estos 30 elementos, no estoy seguro de lo que estás tratando de lograr, pero si quieres lo que sigue, intenta analizar la clase después.

En otras palabras, la clase contiene 30 canciones, visité el sitio y encontré 30 canciones, por lo que podría ser solo para usuarios registrados.

0
Its YZ 5 oct. 2019 a las 21:24

Como parecía que estabas en el camino correcto, no traté de resolver el problema completo y más bien traté de darte una pista que podría ser útil: Hacer webcrapping dinámico .

" ¿Por qué el selenio? ¿No es suficiente la sopa hermosa?

El raspado web con Python a menudo no requiere más que el uso de Beautiful Soup para alcanzar la meta. Beautiful Soup es una biblioteca muy poderosa que hace que el raspado web al atravesar el DOM (modelo de objeto de documento) sea más fácil de implementar. Pero solo hace raspado estático. El raspado estático ignora JavaScript. Obtiene páginas web del servidor sin la ayuda de un navegador. Obtiene exactamente lo que ve en "ver fuente de la página", y luego lo corta y corta. Si los datos que busca están disponibles solo en "ver fuente de la página", no necesita ir más allá. Pero si necesita datos que están presentes en los componentes que se representan al hacer clic en los enlaces de JavaScript, el raspado dinámico viene al rescate. La combinación de Beautiful Soup y Selenium hará el trabajo de raspado dinámico. Selenium automatiza la interacción del navegador web desde Python. Por lo tanto, los datos generados por los enlaces de JavaScript pueden estar disponibles automatizando los clics de los botones con Selenium y luego Beautiful Soup los puede extraer ".https: // medium.com/ymedialabs-innovation/web-scraping-using-beautiful-soup-and-selenium-for-dynamic-page-2f8ad15efe25

Esto es lo que veo al final de las 30 canciones en el DOM que se refiere a un botón:

    </li>
   </ol>
   <button class="link js-action-button" data-track-type="view-all-button">
    View all on Spotify
   </button>
  </div>
1
san 5 oct. 2019 a las 22:44
58252389