Спасибо lorien!!!
Поистине полный и понятный ответ.
Буду рыть во втором направлении - xpath.
import html5lib
from lxml import etree
tree = html5lib.parse("<a href='aaa'>aaa</a>", treebuilder="lxml")
print etree.tostring(tree.getroot())
import html5lib
from lxml import etree
tree = html5lib.parse("<a href='aaa'>aaa</a>", treebuilder="lxml", namespaceHTMLElements=False)
print etree.tostring(tree.getroot())
kivsiak
Думать и писать код за вас я могу, но это будет стоить 25$/h. Могу посоветовать разобраться с тем как работают xpath выражения, и как их применять в libxml.
dmnBrestВсе сходится - чем меньше документации и больше надо трахаться, тем больше цена человека, который умеет с ним работать, ну а каждый хочет набить себе цену :)
Для решения моих задач вполне хватает beautifulsoup, а lxml это всего лишь дань моему любопытству. Прогрессивный народ голосует в пользу второго, но “почему”, никто об этом не говорит.
dmnBrestНу и еще это. Суп у меня, к сожалению, жидко обосрался на первом же реальном документе.
Анализируя материал в инете у меня сложилось мнение, что для задач парсинга html библиотека lxml подходит в меньшей мере (больше для xml), чем скажем тот beautifulsoup, только вот этот, второй, давно не поддерживается автором.
Кроме того использование внутренних средств beautifulsoup для разбора невалидного кода тоже далеко не лучший вариант.
dmnBrestо_О а это как?
Поэтому остается использовать связку html5lib и beautifulsoup, несмотря на грозные предупреждения автора первого продукта о выходе данного метода из моды.
asilyatorот Beautifulsoup я отказался :) в последних сообщениях было найдено решение и оно меня вполне удовлетворяет.dmnBrestо_О а это как?
Поэтому остается использовать связку html5lib и beautifulsoup, несмотря на грозные предупреждения автора первого продукта о выходе данного метода из моды.
tree = html5lib.parse(data, treebuilder="lxml", namespaceHTMLElements=False)
root = tree.getroot()
xpath_abr="//p[contains(., 'ключевое слово') and string-length(text())>'50']" # поиск в тексте абзацев содержащих "ключевое слово" и длиной более 50 символов (и так далее, все зависит от фантазии и знания xpath)
xpath_me = etree.XPath(xpath_abr.decode('utf8'))
nodes = xpath_me(root)
for node in nodes:
if node.text is None: node.text = ''
print etree.tounicode(node).encode('utf8');
asilyatorне понял про “…getpath() и getroot() у меня нет…”
Есть еще вопрос по lxml+html5, предположим, я нашел нужный элемент, а как вывести его путь от корня? В доках нихрена не понятно + они еще и устаревшие (http://codespeak.net/lxml/api/lxml.etree._ElementTree-class.html getpath() и getroot() у меня нет, да и etree.tostring() вместо str(elem) тоже решение спорное).
import html5lib
from lxml import etree
tree = html5lib.parse(page, treebuilder="lxml", namespaceHTMLElements=False) #PAGE - html текст страницы
root = tree.getroot()
xpath_abr="//a"
xpath_me = etree.XPath(xpath_abr.decode('utf8'))
nodes = xpath_me(root)
for node in nodes:
print tree.getpath(node)
/html/body/div[2]/div/div[1]/div/a
/html/body/div[2]/div/div[2]/ul/li[1]/a
/html/body/div[2]/div/div[2]/ul/li[2]/a
/html/body/div[2]/div/div[2]/ul/li[3]/a
/html/body/div[2]/div/div[2]/ul/li[4]/a
/html/body/div[2]/div/div[2]/ul/li[5]/a
/html/body/div[2]/div/div[2]/ul/li[6]/a
/html/body/div[2]/div/div[3]/div/div[2]/div[1]/div[2]/h1/a
/html/body/div[2]/div/div[3]/div/div[2]/div[1]/div[2]/div/a
/html/body/div[2]/div/div[3]/div/div[2]/div[1]/div[3]/div/p[1]/a[1]
/html/body/div[2]/div/div[3]/div/div[2]/div[1]/div[3]/div/p[1]/a[2]
/html/body/div[2]/div/div[3]/div/div[2]/div[1]/div[3]/div/p[1]/a[3]
...
>>> doc.xpath('//*[@id="mail"]')
[<Element li at 3061d08>]