sql >> Database teknologi >  >> RDS >> Mysql

Smuk suppe webscrape ind i mysql

Så der er et par ting at tage fat på her.

dokumenterne på PyMySQL er ret gode til at få dig op at køre.

Før du kan lægge disse ting ind i en database, skal du dog have fat i dem på en måde, så kunstneren og sangens navn er forbundet med hinanden. Lige nu får du en separat liste over kunstnere og sange, uden at du kan forbinde dem. Du vil gerne gentage titlen-kunstnerklassen for at gøre dette.

Jeg ville gøre det sådan -

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

Dette vil udskrive titlen og kunstneren for hver iteration af recordList-løkken.

For at indsætte disse værdier i en MySQL DB oprettede jeg en tabel kaldet artist_song med følgende:

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;

Dette er ikke den reneste måde at gøre det på, men ideen er sund. Vi ønsker at åbne en forbindelse til MySQL DB (jeg har kaldt min DB top_40), og indsætte et kunstner/titel-par for hver iteration af recordList-løkken:

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()

Edit:I henhold til min kommentar synes jeg, det er klarere at iterere over tabelrækkerne i stedet:

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. Almindelige fejl ved migrering af PostgreSQL-databaser fra On-Prem til AWS RDS

  2. Hvordan kan jeg se forespørgsler, der udføres mod Oracle?

  3. En tur gennem GIMR

  4. Store objekter må ikke bruges i auto-commit-tilstand