Красивый суп и извлечение div и его содержимого по ID

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

Почему это НЕ возвращает <div id="articlebody"> ... </div>теги и прочее между ними? Ничего не возвращает И я точно знаю, что он существует, потому что я смотрю прямо на него с

soup.prettify()

soup.find("div", { "id" : "articlebody" }) тоже не работает.

( РЕДАКТИРОВАТЬ: я обнаружил, что BeautifulSoup неправильно анализировал мою страницу, что, вероятно, означало, что страница, которую я пытался проанализировать, не отформатирована должным образом в SGML или чем-то еще)

Тони Старк
источник
(Для вашего РЕДАКТИРОВАНИЯ этот вопрос все еще имеет значение как ресурс для повторного использования для других, даже если парсер не работает на вашей конкретной странице)
smci

Ответы:

202

Вы должны опубликовать свой пример документа, потому что код работает нормально:

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

Поиск <div>s внутри <div>s также работает:

>>> soup = BeautifulSoup.BeautifulSoup('<html><body><div><div id="articlebody"> ... </div></div></body></html')
>>> soup.find("div", {"id": "articlebody"})
<div id="articlebody"> ... </div>
Лукаш Лалинский
источник
2
мой пример документа огромен. Я отслеживаю проблему - я думаю, что это не работает на divs divs. Я подсчитал, сколько div в документе есть с print len ​​(soup ('div')), что привело к 10, и я могу ЯСНО увидеть более 10 div с firebug. так что я думаю, что он просто не может найти div внутри div, поэтому мне нужно сузить вещи оберткой за оберткой.
Тони Старк
8
Ну, тогда невозможно ответить на ваш вопрос, хрустальные шары не являются надежным способом отладки. :)
Лукаш Лалинский
1
Я попробовал этот код. div имеет <embed>, и я не могу напечатать вставку внутри него.
Винсент
13
или более простоdiv = soup.find(id="articlebody")
JFS
4
илиsoup.find('div', id='articlebody')
Тревор Бойд Смит
71

Чтобы найти элемент по его id:

div = soup.find(id="articlebody")
JFS
источник
15

Beautiful Soup 4 поддерживает большинство CSS-селекторов с помощью .select()метода , поэтому вы можете использовать такой idселектор , как:

soup.select('#articlebody')

Если вам нужно указать тип элемента, вы можете добавить селектор типа перед idселектором:

soup.select('div#articlebody')

.select()Метод возвращает коллекцию элементов, а это означает , что она будет возвращать те же результаты, что и следующий .find_all()метод , например:

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

Если вы хотите выбрать только один элемент, вы можете просто использовать .find()метод :

soup.find('div', id="articlebody")
# or
soup.find(id="articlebody")
Джош Крозье
источник
13

Я думаю, что есть проблема, когда теги 'div' слишком сильно вложены. Я пытаюсь проанализировать некоторые контакты из html-файла facebook, и Beautifulsoup не может найти теги "div" с классом "fcontent".

Это происходит и с другими классами. Когда я ищу div в общем, получаются только те, которые не так много вложены.

Исходным кодом html может быть любая страница из Facebook списка друзей вашего друга (не одного из ваших друзей). Если кто-то может проверить это и дать совет, я был бы очень признателен.

Это мой код, где я просто пытаюсь напечатать количество тегов "div" с классом "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)
Omar
источник
9

Скорее всего из-за проблем с парсером Beautifulsoup по умолчанию. Измените другой анализатор, например «lxml», и попробуйте снова.

лян
источник
Это сработало для меня, спасибо! Я использовалsoup = BeautifulSoup(data, parser="html.parser")
Воля Харт
8

В источнике Beautifulsoup эта строка позволяет вложить div в div; так что ваше беспокойство в комментарии Лукаса не будет обоснованным.

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

Я думаю, что вам нужно указать атрибуты, которые вы хотите, такие как

source.find('div', attrs={'id':'articlebody'})
dagoof
источник
5

ты пробовал soup.findAll("div", {"id": "articlebody"})?

звучит безумно, но если вы скребете вещи с дикой природы, вы не можете исключить несколько делений ...

user106514
источник
4

Я использовал:

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

Как мой синтаксис для find / findall; тем не менее, если между тегом и списком атрибутов нет других необязательных параметров, это не должно быть иначе.


источник
4

Случилось и у меня тоже при попытке поцарапать гугл.
Я закончил тем, что использовал pyquery.
Установка:

pip install pyquery

Использование:

from pyquery import PyQuery    
pq = PyQuery('<html><body><div id="articlebody"> ... </div></body></html')
tag = pq('div#articlebody')
Shoham
источник
3

Вот фрагмент кода

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

Как видите, я нахожу все теги, а затем нахожу все теги с class = "article" внутри

Рекурсия
источник
0

IdСвойство всегда однозначно определены. Это означает, что вы можете использовать его напрямую, даже не указав элемент. Поэтому, это положительный момент, если ваши элементы имеют его для анализа содержимого.

divEle = soup.find(id = "articlebody")
Икра.
источник