Найти - Пользователи
Полная версия: beautifulsoup + html5lib обход дерева циклом
Начало » Python для новичков » beautifulsoup + html5lib обход дерева циклом
1 2
andreykyz
сам код:
import urllib2
import html5lib
from html5lib import treebuilders

parser = html5lib.HTMLParser(tree=treebuilders.getTreeBuilder("beautifulsoup"))
soup = parser.parse(urllib2.urlopen("http://a-el.ru/catalog.htm").read())
soup = parser.parse(f)
table_soup = soup.table.tbody.tr.td.table.tbody.tr.nextSibling.nextSibling.tbody
for tag in table_soup:
print tag.contents[0].name
Ошибка:
/var/lib/python-support/python2.6/html5lib/inputstream.py:367: DeprecationWarning: object.__init__() takes no parameters
str.__init__(self, value)
Traceback (most recent call last):
File "./examles.py", line 9, in <module>
print tag.contents[0].name
File "/var/lib/python-support/python2.6/BeautifulSoup.py", line 427, in __getattr__
raise AttributeError, "'%s' object has no attribute '%s'" % (self.__class__.__name__, attr)
AttributeError: 'NavigableString' object has no attribute 'contents'
непонимаю в чем проблема.
regall
andreykyz
'NavigableString' object has no attribute ‘contents’
В BeautifulSoup есть два принципиально разных вида объектов Tag и NavigableString. Разница в том, что Navigable string соответствует текстовой строке и не имеет атрибута contents (по нему нельзя производить поиск в глубину, так как это уже “листик” дерева элементов)
andreykyz
print tag.contents.name
Судя по всему, вылетает здесь, когда в переменной ‘tag’ попадает не тег, а строковое значение
import urllib2
import html5lib
from html5lib import treebuilders

parser = html5lib.HTMLParser(tree=treebuilders.getTreeBuilder("beautifulsoup"))
soup = parser.parse(urllib2.urlopen("http://a-el.ru/catalog.htm").read())
soup = parser.parse(f)
table_soup = soup.table.tbody.tr.td.table.tbody.tr.nextSibling.nextSibling.tbody
for tag in table_soup:
if isinstance(tag, Tag):
print tag.contents[0].name
В таком случае, этот код выведет имена тегов, и пропустит все строки
andreykyz
regall
В BeautifulSoup есть два принципиально разных вида объектов Tag и NavigableString. Разница в том, что Navigable string соответствует текстовой строке и не имеет атрибута contents (по нему нельзя производить поиск в глубину, так как это уже “листик” дерева элементов)
хм понятно.
Тогда может быть подскажете как мне обойти все строчки таблицы и получать не просто string'и, а такие объекты чтобы можно было дальше в глубину по дереву уходить. В общем мне надо распарсить данную таблицу сначала по строчкам, а потом по ячейкам.
regall
trs = soup.findAll(name = "tr")
В результате этого кода вы получите все ветки <tr> {много тегов <td>} </tr>
for tr in trs:
tds = tr.findAll(name = "td")
В tds - получите все теги <td/> в теге <tr/>.

P.S. Также очень полезен бывает следующий вызов
allTags = soup.findAll(True)
Параметр True указывает парсеру найти абсолютно все теги документа (только теги, не строки)
andreykyz
теперь вот такая ошибка:
    print tds
UnicodeEncodeError: 'ascii' codec can't encode characters in position 233-239: ordinal not in range(128)
странно, когда я делал:
soup = parser.parse(open("catalog.htm"))
table_soup = soup.table.tbody.tr.td.table.tbody.tr.nextSibling.nextSibling.tbody
print table_soup.tr
все выводилось без ошибок и по Русски
regall
andreykyz
UnicodeEncodeError: ‘ascii’ codec can't encode characters in position 233-239: ordinal not in range(128)
Эта ошибка описана в документации
http://www.crummy.com/software/BeautifulSoup/documentation.html#Troubleshooting
В качестве workaround попробуйте вывести результат не в консоль, а в файл и там уже смотреть.

P.S. проблемы с кодировками в Python 2.x неоднократно обсуждались на этом форуме, не поленитесь воспользоваться, гарантирую, что найдете для себя много полезной информации
andreykyz
#!/usr/bin/python
# -*- coding: utf-8 -*-
import urllib2
import html5lib
from html5lib import treebuilders

parser = html5lib.HTMLParser(tree=treebuilders.getTreeBuilder("beautifulsoup"))
soup = parser.parse(urllib2.urlopen("http://a-el.ru/catalog.htm").read())
table_soup = soup.table.tbody.tr.td.table.tbody.tr.nextSibling.nextSibling.tbody

print table_soup.tr #вот это работает

trs = soup.findAll(name = "tr")
for tr in trs:
tds = tr.findAll(name = "td")
print unicode(str(tds), 'cp1251') #вот это не работает
/var/lib/python-support/python2.6/html5lib/inputstream.py:367: DeprecationWarning: object.__init__() takes no parameters
str.__init__(self, value)
<tr><th colspan="5" align="center" class="th1"><a name="secure" class="intable">Безопасность</a></th></tr>
Traceback (most recent call last):
File "./examles.py", line 16, in <module>
print unicode(str(tds), 'utf-8')
UnicodeEncodeError: 'ascii' codec can't encode characters in position 233-239: ordinal not in range(128)
это если запусать из файла, а если запускать из консоли python то не работает вообще. Непонимаю проблема в beautifulsoup или в питоне.
PS Ubuntu 9.04
andreykyz
Как я понял ошибка возникает при экспорте из beautifulsoup
andreykyz
Еще не работает вот это :(
parser = html5lib.HTMLParser(tree=treebuilders.getTreeBuilder("beautifulsoup"))
soup = parser.parse(open("catalog.htm"))
table_soup = soup.table.tbody.tr.td.table.tbody.tr.nextSibling.nextSibling.tbody
print soup.contents[0].name # не работает
Traceback (most recent call last):
File "./examles.py", line 15, in <module>
print soup.contents[0].name
File "/var/lib/python-support/python2.5/BeautifulSoup.py", line 427, in __getattr__
raise AttributeError, "'%s' object has no attribute '%s'" % (self.__class__.__name__, attr)
AttributeError: 'Declaration' object has no attribute 'name'
причем soup.name - работает

Скажите хотябы какой версией python, html5lib и BeautifulSoup пользуетесь вы
regall
andreykyz
AttributeError: ‘Declaration’ object has no attribute ‘name’
Опять же, если копнуть глубже в HTML и даже в ваш catalog.hm, то вы наверняка увидите в первой строчке что-то типа такого
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
Это объявление о типе вашего документа. Почитайте тут: http://www.w3schools.com/tags/tag_DOCTYPE.asp

Так вот, выражение
soup.contents[0]
возращает вам как раз это объявление завернутое в объект Declaration. А вот
soup.contents[0].nexSibling
как раз таки должен быть объект - Tag “html”
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB