Як скребти веб-сторінку imdb?


10

Я намагаюся навчитися веб-вискоблюванню за допомогою Python самостійно як частина зусиль для вивчення аналізу даних. Я намагаюся скребити веб-сторінку imdb, URL-адреса якої: http://www.imdb.com/search/title?sort=num_votes,desc&start=1&title_type=feature&year=1950,2012

Я використовую модуль BeautifulSoup. Далі йде код, який я використовую:

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

Я отримую такі результати:

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

Використовуючи цей код, я міг скребкувати заголовок, жанр, час виконання та рік, але я не зміг скребкувати ідентифікаційний код фільму, ні рейтинг. Після огляду елементів (у хромованому браузері) я не в змозі знайти шаблон, який дозволить мені використовувати аналогічний код, як описано вище.

Хтось може допомогти мені написати фрагмент коду, який дозволить мені скребкувати ідентифікатор фільму та рейтинги?


1
Я трохи відредагував ваш код, але він не вдається, оскільки ratingне визначений. Якщо ви виправите це, ви можете також додати from BeautifulSoup import BeautifulSoupі import requests. А чому б і не показати, url="http://etc"щоб ми не мали цього робити для себе?
Спайсмен

Відповіді:


12

Замість того, щоб скребкувати, ви можете спробувати отримати дані безпосередньо тут: http://www.imdb.com/interfaces . Схоже, у них є дані, доступні через ftp для фільмів, акторів тощо.


2
@Gred Thatcher, Дякую за посилання. Цей проект є частиною навчальних зусиль щодо веб-скребки, а отже, і всіх цих проблем. - :)
user62198

8

Я зміг знайти рішення. Я думав надсилати повідомлення про всяк випадок, якщо це комусь допоможе або якщо хтось хоче запропонувати щось інше.

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

Вихід виглядає приблизно так:

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

2

Ви можете отримати все від div з class = "рейтинг-список"

Все, що вам потрібно зробити, це відновити ідентифікатор атрибута: [id = "tt1345836 | imdb | 8.5 | 8.5 | advsearch"] Коли у вас є цей вміст, ви розділите цей рядок на '|', і ви отримаєте: 1. параметр: id фільму 3. параметр: оцінка фільму


Дякую. @Matic DB ... мені вдалося отримати ідентифікатор .. Нижче моє рішення
user62198

2

Як трохи загальних відгуків, я думаю, ви б добре зробили для покращення вихідного формату. Проблема з існуючим форматом полягає в тому, що немає прозорого способу програмного отримання даних. Подумайте замість того, щоб спробувати:

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

Приємна річ у файлі з обмеженими вкладками полягає в тому, що якщо ви закінчите масштабування, його можна легко прочитати в щось на зразок impala (або в менших масштабах, прості таблиці mySql). Крім того, ви можете програмно читати дані в python, використовуючи:

 line.split("\t")

Другий поради, я б запропонував отримати більше інформації, ніж ви вважаєте, що вам потрібно для початкового запису. Місце на диску дешевше, ніж час на обробку, тому повторне повторне використання скрепера кожного разу, коли ви розширюєте свою аналітику, не буде цікавою.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.