2016-03-18 14 views
5

Witam, więc stosuję find_all na beautifulsoup object i znajduję coś, co jest bs4.element.ResultSet object lub list.beautifulsoup: find_all na obiekcie lub liście bs4.element.ResultSet?

Chcę dalej szukać find_all, ale nie jest dozwolone na bs4.element.ResultSet object. Potrafię przeglądać każdy element bs4.element.ResultSet object, aby znaleźć find_all. Ale czy mogę uniknąć pętli i po prostu przekonwertować ją z powrotem na beautifulsoup object?

Zobacz kod po szczegóły. Dzięki

html_1 = """ 
<table> 
    <thead> 
     <tr class="myClass"> 
      <th>A</th> 
      <th>B</th> 
      <th>C</th> 
      <th>D</th> 
     </tr> 
    </thead> 
</table> 
""" 
soup = BeautifulSoup(html_1, 'html.parser') 

type(soup) #bs4.BeautifulSoup 

# do find_all on beautifulsoup object 
th_all = soup.find_all('th') 

# the result is of type bs4.element.ResultSet or similarly list 
type(th_all) #bs4.element.ResultSet 
type(th_all[0:1]) #list 

# now I want to further do find_all 
th_all.find_all(text='A') #not work 

# can I avoid this need of loop? 
for th in th_all: 
    th.find_all(text='A') #works 

Odpowiedz

8

ResultSet klasa jest podklasa listy a nie Tag class który ma find* metody zdefiniowane. Przelotowe wyników find_all() jest najczęstszym podejściem:

th_all = soup.find_all('th') 
result = [] 
for th in th_all: 
    result.extend(th.find_all(text='A')) 

Zazwyczaj CSS selectors może pomóc go rozwiązać za jednym zamachem z wyjątkiem, że nie wszystko można zrobić z find_all() jest możliwe dzięki metodzie select(). Na przykład nie ma wyszukiwania "tekstowego" dostępnego w selektorach CSS bs4. Ale jeśli, na przykład, trzeba było znaleźć wszystko, powiedzmy, b elementy wewnątrz th elementów, można zrobić:

soup.select("th td") 
+0

Po skopiowaniu wyniku soup.find_all do th_all będzie wprowadzenie zmian do th_all odzwierciedlenia w zupa? –

+0

Tak, będzie. Zależy od używanej funkcji. Patrz: https://beautiful-soup-4.readthedocs.io/en/latest/#modifying-the-tree –