Ошибка атрибута Python: объект «NoneType» не имеет атрибута «find_all»

Я пытаюсь получить сокращения штатов США, но этот код:

from bs4 import BeautifulSoup
from urllib.request import urlopen
url='https://simple.wikipedia.org/wiki/List_of_U.S._states'
web=urlopen(url)
source=BeautifulSoup(web, 'html.parser')
table=source.find('table', {'class': 'wikitable sortable jquery-tablesorter'})
abbs=table.find_all('b')
print(abbs.get_text())

возвращает AttributeError: объект «Nonetype» не имеет атрибута «find_all». В чем проблема моего кода?


person Roy Kim    schedule 19.11.2017    source источник
comment
source.find возвращает None, у которого нет атрибута find_all   -  person Patrick Haugh    schedule 19.11.2017
comment
Он не может найти элемент «jquery-tablesorter, сортируемый по викитаблице».   -  person Alex F    schedule 19.11.2017
comment
В HTML это называется 'wikitable sortable'.   -  person Alex F    schedule 19.11.2017
comment
@ Рой, я думаю, мой ответ даст тебе то, что ты ищешь.   -  person Alex F    schedule 19.11.2017


Ответы (3)


Как было предложено в комментариях, HTML в URL-адресе не имеет таблицы с классом

'wikitable sortable jquery-tablesorter'

Но на самом деле класс

'wikitable sortable'

Также, как только вы применяете find_all, он возвращает список, содержащий все теги, поэтому вы не можете напрямую применить к нему get_text(). Вы можете использовать понимание списка, чтобы вырезать текст для каждого элемента в списке. Вот код, который будет работать для вашей проблемы

from bs4 import BeautifulSoup
from urllib.request import urlopen
url='https://simple.wikipedia.org/wiki/List_of_U.S._states'
web=urlopen(url)
source=BeautifulSoup(web, 'html.parser')
table=source.find('table', {'class': 'wikitable sortable'})
abbs=table.find_all('b')
values = [ele.text.strip() for ele in abbs]
print(values)
person Akshay    schedule 19.11.2017

Как предложил Патрик,

source.first() возвращает только первый элемент.

Исходный код метода first() для справки:

def find(self, name=None, attrs={}, recursive=True, text=None, **kwargs):
    """Return only the first child of this Tag matching the given criteria."""
    r = None
    l = self.find_all(name, attrs, recursive, text, 1, **kwargs)
    if l:
        r = l[0]
    return r
findChild = find

После извлечения таблицы имя класса было wikitable sortable.
Таким образом, согласно приведенному выше коду, он возвращал None.

Итак, вы можете изменить свой код как...

from bs4 import BeautifulSoup
from urllib.request import urlopen

url = 'https://simple.wikipedia.org/wiki/List_of_U.S._states'
web = urlopen(url)
source = BeautifulSoup(web, 'html.parser')

table = source.find('table', class_='wikitable')
abbs = table.find_all('b')

abbs_list = [i.get_text().strip() for i in abbs]
print(abbs_list)

Я надеюсь, что это ответит на ваш вопрос. :)

person Mohsin    schedule 19.11.2017
comment
Решил проблему. Большое спасибо! - person Roy Kim; 19.11.2017

Ну вот.

Я изменил класс в source.find на 'wikitable sortable'. Кроме того, метод abbs.get_text() дал мне ошибку, поэтому я просто использовал функцию генератора, чтобы получить нужный текст.

from bs4 import BeautifulSoup
from urllib.request import urlopen

web = urlopen('https://simple.wikipedia.org/wiki/List_of_U.S._states')
source = BeautifulSoup(web, 'lxml')
table = source.find(class_='wikitable sortable').find_all('b')
b_arr = '\n'.join([x.text for x in table])
print(b_arr)

Частичный вывод:

AL
AK
AZ
AR
CA
CO
person Alex F    schedule 19.11.2017
comment
Нет необходимости использовать замену строки, красивый суп дает вам методы для извлечения текста с помощью ele.text.strip() - person Akshay; 19.11.2017