sql >> Database >  >> RDS >> Mysql

Mooie soep webscrape in mysql

Er zijn dus een paar dingen die hier moeten worden aangepakt.

De documenten op PyMySQL zijn er redelijk goed in om u op weg te helpen.

Voordat je deze dingen in een database kunt zetten, moet je ze echter zo pakken dat de artiest en de naam van het nummer met elkaar in verband worden gebracht. Op dit moment krijg je een aparte lijst met artiesten en nummers, zonder manier om ze te associëren. Je zult de titel-artiestklasse willen herhalen om dit te doen.

Ik zou dit zo doen -

from urllib import urlopen
from bs4 import BeautifulSoup
import pymysql.cursors

# Webpage connection
html = urlopen("http://www.officialcharts.com/charts/singles-chart/19800203/7501/")

# Grab title-artist classes and iterate
bsObj = BeautifulSoup(html)
recordList = bsObj.findAll("div", {"class" : "title-artist",})

# Now iterate over recordList to grab title and artist
for record in recordList:
     title = record.find("div", {"class": "title",}).get_text().strip()
     artist = record.find("div", {"class": "artist"}).get_text().strip()
     print artist + ': ' + title

Hiermee worden de titel en artiest afgedrukt voor elke herhaling van de recordList-lus.

Om deze waarden in een MySQL DB in te voegen, heb ik een tabel gemaakt met de naam artist_song met het volgende:

CREATE TABLE `artist_song` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `artist` varchar(255) COLLATE utf8_bin NOT NULL,
  `song` varchar(255) COLLATE utf8_bin NOT NULL,
  PRIMARY KEY (`id`)
  ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin
  AUTO_INCREMENT=1;

Dit is niet de schoonste manier om dit aan te pakken, maar het idee is goed. We willen een verbinding met de MySQL DB openen (ik heb mijn DB top_40 genoemd), en een artiest/titel-paar invoegen voor elke iteratie van de recordList-lus:

from urllib import urlopen
from bs4 import BeautifulSoup
import pymysql.cursors


# Webpage connection
html = urlopen("http://www.officialcharts.com/charts/singles-chart/19800203/7501/")

# Grab title-artist classes and store in recordList
bsObj = BeautifulSoup(html)
recordList = bsObj.findAll("div", {"class" : "title-artist",})

# Create a pymysql cursor and iterate over each title-artist record.
# This will create an INSERT statement for each artist/pair, then commit
# the transaction after reaching the end of the list. pymysql does not
# have autocommit enabled by default. After committing it will close
# the database connection.
# Create database connection

connection = pymysql.connect(host='localhost',
                             user='root',
                             password='password',
                             db='top_40',
                             charset='utf8mb4',
                             cursorclass=pymysql.cursors.DictCursor)

try:
    with connection.cursor() as cursor:
        for record in recordList:
            title = record.find("div", {"class": "title",}).get_text().strip()
            artist = record.find("div", {"class": "artist"}).get_text().strip()
            sql = "INSERT INTO `artist_song` (`artist`, `song`) VALUES (%s, %s)"
            cursor.execute(sql, (artist, title))
    connection.commit()
finally:
    connection.close()

Bewerken:volgens mijn opmerking denk ik dat het duidelijker is om in plaats daarvan de tabelrijen te herhalen:

from urllib import urlopen
from bs4 import BeautifulSoup
import pymysql.cursors


# Webpage connection
html = urlopen("http://www.officialcharts.com/charts/singles-chart/19800203/7501/")

bsObj = BeautifulSoup(html)

rows = bsObj.findAll('tr')
for row in rows:
    if row.find('span', {'class' : 'position'}):
        position = row.find('span', {'class' : 'position'}).get_text().strip()
        artist = row.find('div', {'class' : 'artist'}).get_text().strip()
        track = row.find('div', {'class' : 'title'}).get_text().strip()



  1. [BIJGEWERKT 2020-01-23] Microsoft Office 365 Build 1912 Breekt de identiteit van ODBC Linked Tables

  2. Prestaties van LIKE-query's op miljoenen rijtabellen, MySQL

  3. INITCAP() Functie in Oracle

  4. Hoe kan ik een externe sleutelbeperking afdwingen van niet-gerelateerde tabellen in Mysql?