Come raschiare la pagina web di imdb?


10

Sto provando a imparare da solo il web scraping usando Python come parte di uno sforzo per imparare l'analisi dei dati. Sto cercando di raschiare la pagina web imdb il cui url è il seguente: http://www.imdb.com/search/title?sort=num_votes,desc&start=1&title_type=feature&year=1950,2012

Sto usando il modulo BeautifulSoup. Di seguito è riportato il codice che sto usando:

r = requests.get(url) # where url is the above url    
bs = BeautifulSoup(r.text)
for movie in bs.findAll('td','title'):
    title = movie.find('a').contents[0]
    genres = movie.find('span','genre').findAll('a')
    genres = [g.contents[0] for g in genres]
    runtime = movie.find('span','runtime').contents[0]
    year = movie.find('span','year_type').contents[0]
    print title, genres,runtime, rating, year

Ricevo i seguenti output:

The Shawshank Redemption [u'Crime', u'Drama'] 142 mins. (1994)

Usando questo codice, sono riuscito a racimolare titolo, genere, tempo di esecuzione e anno, ma non sono riuscito a racimolare l'id del film imdb, né la valutazione. Dopo aver ispezionato gli elementi (nel browser Chrome), non riesco a trovare uno schema che mi permetta di usare un codice simile a quello sopra.

Qualcuno può aiutarmi a scrivere il pezzo di codice che mi permetterà di raschiare l'id del film e le classifiche?


1
Ho modificato un po 'il tuo codice ma non funziona perché ratingnon è definito. Se lo risolvi, puoi anche aggiungere from BeautifulSoup import BeautifulSoup, e import requests. E perché non mostrare anche url="http://etc"così non dobbiamo farlo da soli?
Spacedman

Risposte:


12

Invece di raschiare, potresti provare a ottenere i dati direttamente qui: http://www.imdb.com/interfaces . Sembra che abbiano dati disponibili via ftp per film, attori, ecc.


2
@Gred Thatcher, grazie per il link. Questo progetto fa parte di uno sforzo di apprendimento sul web scraping e quindi di tutti questi problemi. - :)
user62198,

8

Sono stato in grado di trovare una soluzione. Ho pensato di postare nel caso in cui fosse di aiuto a qualcuno o se qualcuno volesse suggerire qualcosa di diverso.

bs = BeautifulSoup(r.text)
for movie in bs.findAll('td','title'):
    title = movie.find('a').contents[0]
    genres = movie.find('span','genre').findAll('a')
    genres = [g.contents[0] for g in genres]
    runtime = movie.find('span','runtime').contents[0]
    rating = movie.find('span','value').contents[0]
    year = movie.find('span','year_type').contents[0]
    imdbID = movie.find('span','rating-cancel').a['href'].split('/')[2]
    print title, genres,runtime, rating, year, imdbID

L'output è simile al seguente:

The Shawshank Redemption [u'Crime', u'Drama'] 142 mins. 9.3 (1994) tt0111161

2

Puoi ottenere tutto da div con class = "rating rating-list"

Tutto quello che devi fare è recuperare ID attributo: [id = "tt1345836 | imdb | 8.5 | 8.5 | advsearch"] Quando hai questo contenuto, dividi questa stringa per '|', e ottieni: 1. parametro: id film 3. parametro: punteggio del film


Grazie. @Matic DB ... sono stato in grado di ottenere l'id .. Sotto è la mia soluzione
user62198

2

Come un po 'di feedback generale, penso che faresti bene a migliorare il tuo formato di output. Il problema con il formato così com'è è che non esiste un modo trasparente per ottenere programmaticamente i dati. Considera invece di provare:

print "\t".join([title, genres,runtime, rating, year])

La cosa bella di un file delimitato da tabulazioni è che se finisci per ridimensionarlo, può essere facilmente letto in qualcosa come impala (o su scale più piccole, semplici tabelle mySql). Inoltre, puoi quindi leggere programmaticamente i dati in Python usando:

 line.split("\t")

Il secondo consiglio è che suggerirei di ottenere più informazioni di quelle che ritieni necessarie sul tuo scrap iniziale. Lo spazio su disco è più economico del tempo di elaborazione, quindi rieseguire il raschietto ogni volta che si espande l'analitica non sarà divertente.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.