Не удается напечатать «None» с Beautifulsoup: объект «NoneType» не является подписным - PullRequest
0 голосов
/ 12 июня 2018

Я пытался найти решение в вопросах, найденных здесь, но не смог найти решение, которое дало бы мне какое-то решение или схожий подход к моей проблеме.Я очень плохо знаком с Python и в качестве первого шага я хотел научиться чистить данные из IMDB, используя красивый суп.Я хочу наскрести название фильма, рейтинг IMDB и количество голосов.В списке есть фильмы, которые не имеют рейтинга и количества голосов, и я получаю: Большое спасибо за все ваши комментарии.Полная обратная трассировка следующая: обратная трассировка (последний вызов был последним): файл "C: /Users/nmartine/PycharmProjects/ratings_ScraperMetracritic/venv/ratings_ScraperMetacritic.py", строка 24, в Голосах = container.find ('span', attrs)= {'name': 'nv'}) ['data-value'] TypeError: объект "NoneType" не может быть подписан "в моем выводе, когда python не находит оценку или голоса.Я правильно получаю названия заголовков, но хочу, чтобы вывод возвращал «Нет», если заголовок не имеет IMDB или количества голосов.Это мой код:

from requests import get
from bs4 import BeautifulSoup

url = 'https://www.imdb.com/search/title?release_date=2014-01-01,2018-12-31&count=250&page=3&sort=moviemeter,asc&ref_=adv_nxt'  
response = get(url)  
html_soup = BeautifulSoup(response.text, 'html.parser')  
type(html_soup)

program_containers = html_soup.find_all('div', class_ = 'lister-item mode- 
advanced')
print(len(program_containers))

for container in program_containers:

name = container.h3.a.text
print(name)

if (container.strong):
    imdb = float(container.strong.text)
    print(imdb)
else: 'None'

votes = container.find('span', attrs= {'name':'nv'})['data-value']
print(votes)

Надеюсь, кто-нибудь может мне помочь!Спасибо!

1 Ответ

0 голосов
/ 12 июня 2018

Доступ к 'data-value', кажется, вызывает текущую проблему, так как find('span', attrs= {'name':'nv'}) должен вернуть объект BeautifulSoup для ['data-value'], чтобы быть успешным.Однако вместо 'data-value' можно использовать атрибут text вместе с getattr.getattr попытается получить доступ к атрибуту text из результата find('span', attrs= {'name':'nv'}), однако, если последний равен None (который не имеет атрибута text), будет возвращен сам None, являющийсясначала указывается в качестве третьего параметра в getattr:

from bs4 import BeautifulSoup as soup
import requests, re
from typing import NamedTuple
class Movie(NamedTuple):
  title:str
  rating:str
  votes:str

def get_films(placeholder=None):
  d = soup(requests.get('https://www.imdb.com/search/title?release_date=2014-01-01,2018-12-31&count=250&page=3&sort=moviemeter,asc&ref_=adv_nxt').text, 'html.parser')
  films = [i for i in d.find_all('div', {'class':re.compile('lister-item[\w\W]+')})]
  final_films = [[getattr(i.find(*c), 'text', placeholder) for c in [['a'], ['strong'], ['span', {'name':'nv'}]]] for i in films] 
  return [Movie(a, b, c) for a, b, c in final_films if a != ' \n']

new_films = get_films()

Первые десять элементов в new_films:

[Movie(title='The OA', rating='7.8', votes='54,496'), Movie(title='Parmanu: The Story of Pokhran', rating='8.5', votes='4,116'), Movie(title='Batman Ninja', rating='5.7', votes='6,847'), Movie(title='Verónica', rating='6.2', votes='20,634'), Movie(title='Set It Up', rating=None, votes=None), Movie(title='Wynonna Earp', rating='7.5', votes='11,771'), Movie(title='Spectre', rating='6.8', votes='333,593'), Movie(title='Van Helsing', rating='6.0', votes='10,719'), Movie(title='The Year of Spectacular Men', rating='6.6', votes='64'), Movie(title='The Heretics', rating='4.8', votes='298')]

Обратите внимание, что для некоторых фильмов в списке рейтинг и голосаотсутствует в списке, и это решение просто предоставляет None вместо него:

[Movie(title="Tom Clancy's Jack Ryan", rating=None, votes=None)]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...