Beautiful Soup возвращает тег элемента, но обрабатывает его как нетипичный

#python #web-scraping #beautifulsoup

#python #очистка веб-страниц #beautifulsoup

Вопрос:

С помощью BeautifulSoup я перебираю строки таблицы. Каждая строка имеет несколько элементов привязки, и я хочу получить значение первого.

Одна строка выглядит следующим образом

 <tr> 
    <td>155</td>
    <td><img alt="yada" src="yada"/> <a href="yada">Genesect</a></td>
    <td><a href="yada"><img alt="Kaefer" src="yada"/></a> <a href="yada"><img alt="Stahl" src="yada"/></a></td>
</tr>

 

Итак, это мой цикл и то, как я пытаюсь получить значение первого элемента привязки

 for row in pkmn_rows:
    name_anchor = row.find('a')
    name = name_anchor.'???'
 

С row.find('a) помощью я получаю первый элемент привязки, так что это <a href="yada">Genesect</a></td> — я проверил это с помощью инструкций print. Даже тип name_anchor есть <class 'bs4.element.Tag'> .

Поэтому не должно быть так сложно извлечь только текстовое значение. Я просмотрел документацию, поискал в Google и нашел пару возможных решений, таких как:

  • name_anchour.text
  • name_anchour.string
  • name_anchour.value
  • name_anchour.contents[0]

Но ничего не работает, так как каждый раз, когда я получаю ошибку:

 Traceback (most recent call last):
  File "soup.py", line 17, in <module>
    print(name_anchor.string)
AttributeError: 'NoneType' object has no attribute 'string'
 

Как я понимаю, ‘NoneType’ указывает, что name_anchor имеет значение null, но это не может быть правдой, поскольку различные операторы печати показывают содержимое и тип.

Я совершаю глупую ошибку?

Комментарии:

1. можете ли вы поделиться фактической ссылкой?

2. Фактическая ссылка на веб-страницу, которую я удаляю: bisafans.de/pokedex/listen/regionaldex.php?dex=einall

3. Со ссылками идут некоторые элементы «None». Я ухожу на ужин.. проверю его, как только вернусь.

Ответ №1:

Если вы найдете все строки из таблицы через pkmn_rows = page.findAll("tr") , он вернет даже <tr><th>..</th></tr> строку. У этого нет элемента привязки, и это приводит к ошибке : AttributeError: 'NoneType' object has no attribute 'string'

Чтобы получить имена из строк, вы можете использовать индекс, подобный этому, внутри вашего for цикла pkmn_rows[1:]

Полный пример:

 from bs4 import BeautifulSoup
import requests

r = requests.get(<insert_url_here>)
page = BeautifulSoup(r.content, 'html.parser')
pkmn_rows = page.findAll("tr")

for row in pkmn_rows[1:]:
    name_anchor = row.find("a")
    print(name_anchor.string)
 

Комментарии:

1. Это сработало — значит, ошибка была в элементе первой строки, который действительно был пустым. Чистый код помог бы, если бы я только сделал проверку if, если строка возвращает элемент <a> . Большое спасибо.

2. Рад, что смог помочь 🙂 Пожалуйста, рассмотрите возможность голосования или утверждения ответа, если это помогло 🙂