Можете ли вы перебирать только теги с помощью итератора .children из BeautifulSoup?

#python #beautifulsoup

#python #beautifulsoup

Вопрос:

Я извлекаю XML-файл с помощью BeautifulSoup с помощью этого кода

 dlink = r'https://www.sec.gov/Archives/edgar/data/1040188/000104018820000126/primary_doc.xml'
dreq = requests.get(dlink).content
dsoup = BeautifulSoup(dreq, 'lxml') 
 

Есть уровень, к которому я пытаюсь получить доступ, а затем поместить элементы в словарь. У меня это работает с этим кодом:

 if dsoup.otherincludedmanagerscount.text != '0':
    inclmgr = []
    for i in dsoup.find_all('othermanagers2info'):
        for m in i.find_all('othermanager2'):
            for o in m.find_all('othermanager'):
                imd={}
                if o.cik:
                    imd['cik'] = o.cik.text
                if o.form13ffilenumber:
                    imd['file_no'] = o.form13ffilenumber.text
                imd['name'] = o.find('name').text
                inclmgr.append(imd)
    comp_dict['incl_mgr'] = inclmgr
 

Я предполагаю, что проще использовать генераторы .children или .descendants, но каждый раз, когда я его запускаю, я получаю сообщение об ошибке. Есть ли способ перебирать только теги, используя генераторы BeautifulSoup?

Что-то вроде этого?

 for i in dsoup.othermanagers2info.children:
        imd['cik'] = i.cik.text

AttributeError: 'NavigableString' object has no attribute 'cik'
 

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

1. Каков ожидаемый результат?

2. Вы можете проверить тип i . Если это строка, пропустите ее.

3. @MendelG список диктовок

4. @Barmar Да, я надеялся, что есть ярлык, кроме isinstance() , но я думаю, что нет.

Ответ №1:

Предполагается othermanagers2info , что это один элемент; вы можете создать те же результаты, используя цикл 1 for:

 for i in dsoup.find('othermanagers2info').find_all('othermanager'):     
    imd={}
    if i.cik:
        imd['cik'] = i.cik.text
    if i.form13ffilenumber:
        imd['file_no'] = i.form13ffilenumber.text
    imd['name'] = i.find('name').text
    inclmgr.append(imd)
comp_dict['incl_mgr'] = inclmgr
 

Вы также можете сделать for i in dsoup.find('othermanagers2info').findChildren(): . Однако это приведет к другим результатам (если вы не добавите дополнительный код). Список будет выровнен и будет включать как родительские, так и дочерние элементы. Вы также можете передать имя узла