Home > Software design >  Scrape Spotify using Python
Scrape Spotify using Python

Time:05-13

Im getting the AttributeError: 'NoneType' object has no attribute 'find' error. Before posting here with some research, possible problem could be that Cloudflare is blocking my access to Spotify. What would be thje workaround to this problem?

part of code looks like this:

dates=[]
urls=[]
final=[]

url = 'https://spotifycharts.com/regional/us/daily'
start_date = date(2022,3,1)
end_date = date(2022,4,30)
delta = end_date - start_date

# print(delta.days 1)

for i in range(delta.days 1):
    day= start_date  timedelta(days=i)
    day_string =day.strftime('%Y-%m-%d')
    dates.append(day_string)



def add_url():
    for date in dates:
        c_string=url date
        urls.append(c_string)

add_url()

def song_scrape(x):
    pg = x
    for tr in songs.find("tbody").findAll("tr"):
        artist = tr.find("td", {"class": "chart-table-track"}).find("span").text
        artist = artist.replace("by ", "").strip()

        title = tr.find("td", {"class": "chart-table-track"}).find("strong").text
        songid = tr.find("td", {"class": "chart-table-image"}).find("a").get("href")
        songid = songid.split("track/")[1]
        url_date = x.split("daily/")[1]
        final.append([title, artist, songid, url_date])


for u in urls:
    read_pg= requests.get(u)
    sleep(2)
    # return read_pg.status_code
    soup= BeautifulSoup(read_pg.content, "html.parser")
    songs = soup.find("table", {"class": "chart-table"})
    song_scrape(u)


final_df = pd.DataFrame(final, columns= ["Title", "Artist", "Song ID", "Chart Date"])
with open('spmooddata.csv', 'w') as f:
        final_df.to_csv(f, header= True, index=False)

CodePudding user response:

As I mentioned in my comment, you need the add certain code as is shown in this answer for solve the 403 forbidden error.

After making more changes to your code, I was able to get the data.

This is your modified and working code:

# Library/module imports
import requests
from bs4 import BeautifulSoup
from datetime import datetime, timedelta
from time import sleep
import pandas as pd

# Variables: 
dates=[]
urls=[]
final=[]
url = 'https://spotifycharts.com/regional/us/daily/'
start_date = datetime(2022,3,1)
end_date = datetime(2022,3,5)
delta = end_date - start_date

# print(delta.days 1)

for i in range(delta.days 1):
  day= start_date   timedelta(days=i)
  day_string =day.strftime('%Y-%m-%d')
  dates.append(day_string)

def add_url(): 
  for date in dates:
    c_string=url date
    urls.append(c_string)

add_url()

def song_scrape(x, songs):
  pg = x
  for tr in songs.find("tbody").findAll("tr"): 
    artist = tr.find("td", {"class": "chart-table-track"}).find("span").text
    artist = artist.replace("by ", "").strip()
    
    title = tr.find("td", {"class": "chart-table-track"}).find("strong").text
    songid = tr.find("td", {"class": "chart-table-image"}).find("a").get("href")
    songid = songid.split("track/")[1]
    url_date = x.split("daily/")[1]
    final.append([title, artist, songid, url_date])


# Avoid http 403 forbidden error with this code: 
# Source: https://stackoverflow.com/a/43590290/12511801 
header = {
  "User-Agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.75 Safari/537.36",
  "X-Requested-With": "XMLHttpRequest"
}

for u in urls:
  read_pg= requests.get(u, headers=header)
  sleep(2)
  # return read_pg.status_code
  soup= BeautifulSoup(read_pg.text, "html.parser")

  #Using BeautifulSoup, we're getting the specific data from the HTML: 
  # There is only 1 table = which is the table with the data to extract:
  songs = soup.findAll("table")[0]

  # Call "song_scrape" function to retrieve the data from the table: 
  song_scrape(u, songs)

final_df = pd.DataFrame(final, columns= ["Title", "Artist", "Song ID", "Chart Date"])
# print(final_df) # Print the dataframe, if you want

with open('spmooddata.csv', 'w') as f: 
  final_df.to_csv(f, header= True, index=False)
  • Related