Код Beautiful Soup возвращает ошибку "AttributeError" - PullRequest
1 голос
/ 11 июля 2020

Я создаю веб-сканер, который возвращает названия кафе, написанные на веб-сайте, например: <h2 class="venue-title" itemprop="name">Prior</h2> Однако он возвращает эту ошибку:

"Объект ResultSet не имеет атрибута '% s '. Вы, вероятно, обрабатываете список элементов как один элемент. Вы вызывали find_all (), когда хотели вызвать find ()? " % key AttributeError: объект ResultSet не имеет атрибута «текст». Вы, вероятно, относитесь к списку элементов как к единственному элементу. Вы вызывали find_all (), когда хотели вызвать find ()? [Завершено через 0,699 с]

Вот код:

from bs4 import BeautifulSoup
import requests

url = 'https://www.broadsheet.com.au/melbourne/guides/best-cafes-thornbury'
response = requests.get(url, timeout=5)

soup_cafe_list = BeautifulSoup(response.content, "html.parser")
type(soup_cafe_list)

cafes = soup_cafe_list.findAll('h2', attrs_={"class":"venue-title"}).text
print(cafes)

Я перепробовал целый ряд вещей, чтобы понять это. Я чувствую, что это как-то связано с findAll arg: cafes = soup_cafe_list.findAll('h2', attrs_={"class":"venue-title"}).text, потому что, когда я запускаю его как cafes = soup_cafe_list.findAll('h2', class_="venue-title") вместо этого, он вроде ожидает, что не возвращает элементы, очищенные от их html, которые, как я считаю, .text должны делать?

Еще одна вещь, которую я заметил в трассировке, это то, что она может относиться к другому каталогу для BS4? Может ли это иметь какое-либо отношение к этому, я начал использовать Jupyter, а теперь нахожусь на Atom, но, возможно, неправильно установил bs4:

File "/ Users / [xxxxxxxx] / Desktop / Coding / amvpscraper /webscraper.py ", строка 10, в cafes = soup_cafe_list.findAll ('h2', attrs _ = {" class ":" location-title "}). text File" / Users / [xxxxxxxx] / opt / anaconda3 / lib /python3.7/site-packages/bs4/element.py ", строка 2081, в getattr

Не уверен, что делаю что-то еще не так ...

1 Ответ

1 голос
/ 11 июля 2020

Ошибка указывает на то, что возвращаемое значение метода findAll является списком элементов и не имеет текстового атрибута. Сохраните результат в списке (без метода .text) и замените attrs_ на attrs:

cafes = soup_cafe_list.findAll('h2', attrs={"class":"venue-title"})

, а затем переберите список и получите текст. Вы можете сделать это с помощью списка:

cafes = [el.text for el in cafes]

Edit : понимание списка упрощает a для l oop. Вы также можете написать:

res_list = []
for el in cafes:
    res_list.append(el.text)

Кроме того, вы можете добавить предложение try-except или проверку правильности текстового поля в l oop, чтобы перехватить возможные элементы без текста.

Вывод:

['Prior',
 'Rat the Cafe',
 'Ampersand Coffee and Food',
 'Umberto Espresso Bar',
 'Brother Alec',
 'Short Round',
 'Jerry Joy',
 'The Old Milk Bar',
 'Little Henri',
 'Northern Soul']
...