Beautiful Soup i wyodrębnianie elementu div i jego zawartości przez identyfikator


147
soup.find("tagName", { "id" : "articlebody" })

Dlaczego to NIE zwraca <div id="articlebody"> ... </div>tagów i innych elementów? Nic nie zwraca. I wiem na pewno, że istnieje, ponieważ patrzę na to od razu

soup.prettify()

soup.find("div", { "id" : "articlebody" }) też nie działa.

( EDYCJA: Odkryłem, że BeautifulSoup nie analizował poprawnie mojej strony, co prawdopodobnie oznaczało, że strona, którą próbowałem przeanalizować, nie jest poprawnie sformatowana w SGML lub czymkolwiek)


(Do twojej EDYCJI, to pytanie nadal ma wartość jako zasób wielokrotnego użytku dla innych, nawet jeśli parser nie działa na twojej konkretnej stronie)
smci

Odpowiedzi:


202

Powinieneś zamieścić swój przykładowy dokument, ponieważ kod działa dobrze:

>>> import BeautifulSoup
>>> soup = BeautifulSoup.BeautifulSoup('<html><body><div id="articlebody"> ... </div></body></html')
>>> soup.find("div", {"id": "articlebody"})
<div id="articlebody"> ... </div>

Znajdowanie <div>s w środku <div>działa również:

>>> soup = BeautifulSoup.BeautifulSoup('<html><body><div><div id="articlebody"> ... </div></div></body></html')
>>> soup.find("div", {"id": "articlebody"})
<div id="articlebody"> ... </div>

2
mój przykładowy dokument jest ogromny. szukam problemu - myślę, że to nie działa w przypadku elementów div lub div. Policzyłem, ile elementów div znajduje się w dokumencie z print len ​​(zupa („div”)), co dało 10 i WYRAŹNIE widzę ponad 10 elementów div z firebug. więc myślę, że po prostu nie może znaleźć elementów div w elementach div, więc muszę zawęzić zawartość opakowania według opakowania.
Tony Stark

8
Cóż, nie można odpowiedzieć na twoje pytanie, kryształowe kule nie są niezawodnym sposobem debugowania. :)
Lukáš Lalinský

1
Wypróbowałem ten kod. div ma <embed> i nie mogę wydrukować w nim osadzonego.
Vincent,


4
lubsoup.find('div', id='articlebody')
Trevor Boyd Smith

71

Aby znaleźć element według jego id:

div = soup.find(id="articlebody")

15

Piękne Soup 4 obsługuje większość selektorów CSS z .select()metodą , dlatego można użyć idprzełącznika , takie jak:

soup.select('#articlebody')

Jeśli chcesz określić typ elementu, możesz dodać selektor typu przed idselektorem:

soup.select('div#articlebody')

.select()Sposób powraca zbiór elementów, co oznacza, że będzie takie same wyniki, jak w następującej .find_all()metody np

soup.find_all('div', id="articlebody")
# or
soup.find_all(id="articlebody")

Jeśli chcesz wybrać tylko jeden element, możesz po prostu użyć .find()metody :

soup.find('div', id="articlebody")
# or
soup.find(id="articlebody")

13

Myślę, że występuje problem, gdy znaczniki „div” są zbyt zagnieżdżone. Próbuję przeanalizować niektóre kontakty z pliku html Facebooka, a Beautifulsoup nie jest w stanie znaleźć tagów „div” z klasą „fcontent”.

Dzieje się tak również w przypadku innych klas. Kiedy ogólnie wyszukuję elementy div, zwraca tylko te, które nie są zagnieżdżone.

Kod źródłowy html może być dowolną stroną z Facebooka listy znajomych twojego znajomego (nie jednego z twoich znajomych). Jeśli ktoś może to przetestować i udzielić porady, byłbym bardzo wdzięczny.

To jest mój kod, w którym po prostu spróbuję wydrukować liczbę tagów „div” z klasą „fcontent”:

from BeautifulSoup import BeautifulSoup 
f = open('/Users/myUserName/Desktop/contacts.html')
soup = BeautifulSoup(f) 
list = soup.findAll('div', attrs={'class':'fcontent'})
print len(list)

9

Najprawdopodobniej z powodu domyślnego parsera beautifulsoup ma problem. Zmień inny parser, na przykład „lxml” i spróbuj ponownie.


To zadziałało dla mnie, dzięki! Użyłemsoup = BeautifulSoup(data, parser="html.parser")
will-hart

8

W źródle beautifulsoup ta linia pozwala na zagnieżdżanie elementów div w elementach div; więc twoja troska w komentarzu Lukasa nie byłaby uzasadniona.

NESTABLE_BLOCK_TAGS = ['blockquote', 'div', 'fieldset', 'ins', 'del']

Myślę, że musisz określić atrybuty, które chcesz, takie jak

source.find('div', attrs={'id':'articlebody'})

5

próbowałeś soup.findAll("div", {"id": "articlebody"})?

brzmi szalenie, ale jeśli usuwasz rzeczy z natury, nie możesz wykluczyć wielu elementów div ...


4

Użyłem:

soup.findAll('tag', attrs={'attrname':"attrvalue"})

Jako moja składnia dla find / findall; To powiedziawszy, o ile nie ma innych opcjonalnych parametrów między tagiem a listą atrybutów, nie powinno to być inne.


4

Zdarzyło mi się również, gdy próbowałem zeskrobać Google.
Skończyło się na użyciu pyquery.
Zainstalować:

pip install pyquery

Posługiwać się:

from pyquery import PyQuery    
pq = PyQuery('<html><body><div id="articlebody"> ... </div></body></html')
tag = pq('div#articlebody')

3

Oto fragment kodu

soup = BeautifulSoup(:"index.html")
titleList = soup.findAll('title')
divList = soup.findAll('div', attrs={ "class" : "article story"})

Jak widać, znajduję wszystkie tagi, a następnie znajduję wszystkie tagi z atrybutem class = "article" w środku


0

IdNieruchomość jest zawsze identyfikowany. Oznacza to, że możesz go używać bezpośrednio, nawet bez określania elementu. Dlatego jest to plus, jeśli twoje elementy mają to do przeanalizowania zawartości.

divEle = soup.find(id = "articlebody")
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.