Красивый суп, получающий первого ребенка

Как я могу получить первый ребенок?

 <div class="cities"> 
       <div id="3232"> London </div>
       <div id="131"> York </div>
  </div>

Как я могу получить Лондон?

for div in nsoup.find_all(class_='cities'):
    print (div.children.contents)

AttributeError: объект 'listiterator' не имеет атрибута 'contents'

Ответ 1

div.children возвращает итератор.

for div in nsoup.find_all(class_='cities'):
    for childdiv in div.find_all('div'):
        print (childdiv.string) #london, york

Атрибут AttributeError был поднят, поскольку не теги, такие как '\n', находятся в .children. просто используйте правильный дочерний селектор, чтобы найти конкретный div.

(больше прав) не может воспроизвести ваши исключения - вот что я сделал:

In [137]: print foo.prettify()
<div class="cities">
 <div id="3232">
  London
 </div>
 <div id="131">
  York
 </div>
</div>

In [138]: for div in foo.find_all(class_ = 'cities'):
   .....:     for childdiv in div.find_all('div'):
   .....:         print childdiv.string
   .....: 
 London 
 York 

In [139]: for div in foo.find_all(class_ = 'cities'):
   .....:     for childdiv in div.find_all('div'):
   .....:         print childdiv.string, childdiv['id']
   .....: 
 London  3232
 York  131

Ответ 2

В современных версиях bs4 (конечно, bs4 4.7. 1+) у вас есть доступ к псевдо-селектору css от первого ребенка. Хороший и описательный.

from bs4 import BeautifulSoup as bs

html = '''
<div class="cities"> 
       <div id="3232"> London </div>
       <div id="131"> York </div>
  </div>
  '''
soup = bs(html, 'lxml') #or 'html.parser'
first_children = [i.text for i in soup.select('.cities div:first-child')]
print(first_children)

Ответ 3

Текущий принятый ответ получает все города, когда вопрос был задан только первым.

Если вам нужен только первый ребенок, вы можете воспользоваться .children, возвращая итератор, а не список. Помните, что итератор генерирует элементы списка на лету, и поскольку нам нужен только первый элемент итератора, нам никогда не нужно генерировать все другие элементы города (таким образом, экономя время).

for div in nsoup.find_all(class_='cities'):
    first_child = next(div.children, None)
    if first_child is not None:
        print(first_child.string.strip())