2017-01-10 5 views
0

Элемент .select() позволяет мне получить элемент с веб-страницы на основе селектора css, но это будет искать всю веб-страницу. Как использовать .select(), но искать только дочерние элементы определенного элемента. Например:Python Beautiful Soup 4 Get Children of Element with .select()

<!-- Simplified example of the structure --> 
<ul> 
    <li> 
     <div class="foo">foo content</div> 
     <div class="bar">bar content</div> 
     <div class="baz">baz content</div> 
    </li> 
    <li> 
     <!-- We can't assume that foo, bar, and baz will always be there --> 
     <div class="foo">foo content</div> 
     <div class="baz">baz content</div> 
    </li> 
    <li> 
     <div class="foo">foo content</div> 
     <div class="bar">bar content</div> 
     <div class="baz">baz content</div> 
    </li> 
</ul> 

Я хочу способ сказать: для <li> [0] Foo содержала значение "foo content", бар содержал значение "bar content" и т.д ..

В настоящее время мое решение заключается в следующем:

foos = soup.select("div.foo") 
bars = soup.select("div.bar") 
bazs = soup.select("div.baz") 

for i in range(len(foos)): 
    print("{i} contains: {} and {} and {}".format(i=i, foos[i], bars[i], bazs[i])) 

Это работает по большей части. Но он полностью разваливается, когда элемент отсутствует в одном из них. Как я показал в HTML, мы не можем предположить, что будут присутствовать три бара, baz и foo.

Таким образом, как бы я искал только детей из lis. Таким образом, я мог бы сделать что-то вроде этого:

for i in soup.select("li"): 
    #how would i do this: 
    foo = child_of("li", "div.foo")???? 
    bar = child_of("li", "div.bar")???? 
    baz = child_of("li", "div.baz")???? 

ответ

1

Вы можете использовать element:nth-of-type(n) так:

from bs4 import BeautifulSoup 

a = """<!-- Simplified example of the structure --> 
<ul> 
    <li> 
     <div class="foo">foo1 content</div> 
     <div class="bar">bar1 content</div> 
     <div class="baz">baz1 content</div> 
    </li> 
    <li> 
     <!-- We can't assume that foo, bar, and baz will always be there --> 
     <div class="foo">foo2 content</div> 
     <div class="baz">baz2 content</div> 
    </li> 
    <li> 
     <div class="foo">foo3 content</div> 
     <div class="bar">bar3 content</div> 
     <div class="baz">baz3 content</div> 
    </li> 
</ul> 
""" 

s = BeautifulSoup(a) 
s2 = s.select('ul > li:nth-of-type(2)')[0] 
foo, bar, baz = s2.select('div.foo'), s2.select('div.bar'), s2.select('div.baz') 
print foo, bar, baz 

Выход:

[<div class="foo">foo2 content</div>] [] [<div class="baz">baz2 content</div>] 
0
for li in soup.select('li'): 
    foo = li.select('.foo') 
    bar = li.select('.bar') 
    baz = li.select('.baz') 

каждый раз, когда вы перебрать li тега и используйте select(), html-код, который нужно выбрать, - это только содержимое тега li, lik е:

<li> 
    <div class="foo">foo content</div> 
    <div class="bar">bar content</div> 
    <div class="baz">baz content</div> 
</li> 

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

0

Это работает для меня, и все FOOS, бары и bazs хранятся в отдельных списках

foos = [] 
bars = [] 
bazs = [] 
for i in soup.find_all('li'): 
    soup2 = BeautifulSoup(str(i)) 
    print soup2 
    for _ in soup2.find_all('div', {'class':'foo'}): 
     foos.append(_) 
    for _ in soup2.find_all('div', {'class': 'bar'}): 
     bars.append(_) 
    for _ in soup2.find_all('div', {'class': 'baz'}): 
     bazs.append(_)