我怎样才能得到第一个孩子?
<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'
答案 0 :(得分:5)
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
答案 1 :(得分:2)
对于现代版本的bs4(当然是bs4 4.7.1+),您可以使用:first-child 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)
答案 2 :(得分:0)
当问题只想要第一个时,当前接受的答案将覆盖所有城市。
如果只需要第一个孩子,则可以利用.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())