Получение элементов в списке с использованием BS4, приводящее к AttributeError - PullRequest
0 голосов
/ 14 января 2019

Я пытаюсь собрать информацию из раздела статьи в Википедии на сегодняшнюю дату. Когда я получаю информацию со страницы, используя BS4, я использую метод для поиска второго ul (это соответствует всему тексту в разделе «События»). Мне нужен текст в этом разделе статьи. Мой текущий код следующий:

time = datetime.now()
day = time.strftime('%B') + '_' + str(int(time.strftime('%d')))
Label(text = 'ON THIS DAY', font = ('Verdana 12 bold')).grid(column = 1, row = 1, in_ = frame2, padx = 10)
url = 'https://en.wikipedia.org/wiki/' + str(day)
res = requests.get(url)
something = bs4.BeautifulSoup(res.text, features="html.parser")
events = something.find_all('ul')[1]
x = [x.text for x in events]
print(x)

Приведенный выше код вызывает следующую ошибку Python:

Traceback (most recent call last):
  File "D:\Program Files\Python\Python37\MyScripts\RSSFeed\RSSFeed.py", line 74, in <module>
    load()
  File "D:\Program Files\Python\Python37\MyScripts\RSSFeed\RSSFeed.py", line 71, in load
    onthisday()
  File "D:\Program Files\Python\Python37\MyScripts\RSSFeed\RSSFeed.py", line 64, in onthisday
    x = [x.text for x in events]
  File "D:\Program Files\Python\Python37\MyScripts\RSSFeed\RSSFeed.py", line 64, in <listcomp>
    x = [x.text for x in events]
  File "D:\Program Files\Python\Python37\lib\site-packages\bs4\element.py", line 742, in __getattr__
    self.__class__.__name__, attr))
AttributeError: 'NavigableString' object has no attribute 'text'

Я знаю, что эта ошибка происходит из-за того, что события - это всего лишь элемент из списка, но как мне это исправить? (Кстати, я посмотрел ответы на другие вопросы, и у всех возникла та же ошибка в моем.)

1 Ответ

0 голосов
/ 14 января 2019

Когда вы делаете soup.find_all('ul')[1], вы захватываете этот конкретный элемент. Как только вы это сделаете, вам нечего итерировать, если вы не сделаете еще один find_all. Вы можете просто преобразовать все это в текст, а затем разбить на каждую новую строку

import requests
import bs4


response = requests.get('https://en.wikipedia.org/wiki/January_14')

soup = bs4.BeautifulSoup(response.text, 'html.parser')

events = soup.find_all('ul')[1]
events_list = events.text.split('\n')

print(events_list)

или если вы хотите сделать понимание списка, как вы изначально планировали, вы должны найти все эти теги в пределах events (я выбрал <li>), а затем вы можете выполнить итерацию по ним:

import requests
import bs4


response = requests.get('https://en.wikipedia.org/wiki/January_14')

soup = bs4.BeautifulSoup(response.text, 'html.parser')

events = soup.find_all('ul')[1]
indv_event = events.find_all('li')

x = [x.text for x in indv_event]

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

from datetime import datetime

time = datetime.now()
day = time.strftime('%B') + '_' + str(int(time.strftime('%d')))

# Not too familiar with this line. Looks like for tKinter
Label(text = 'ON THIS DAY', font = ('Verdana 12 bold')).grid(column = 1, row = 1, in_ = frame2, padx = 10)

url = 'https://en.wikipedia.org/wiki/' + str(day)
res = requests.get(url)

something = bs4.BeautifulSoup(res.text, features="html.parser")

events = something.find_all('ul')[1]
indv_event = events.find_all('li')

x = [x.text for x in indv_event]
print(x)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...