Как разделить теги из дерева HTML - PullRequest
0 голосов
/ 09 января 2012

Это мое дерево html

 <li class="taf"><h3><a href="26eOfferCode%3DGSONESTP-----------" id="pa1">
    Citibank <b>Credit Card</b> - Save over 5% on fuel | Citibank.co.in</a>
   </h3>Get the IndianOil Citibank <b>Card</b>. Apply Now! 
   <br />
   <a href="e%253DGOOGLE ------">Get 10X Rewards On Shopping</a> -
   <a href="S%2526eOfferCode%253DGSCCSLEX ------">Save Over 5% On Fuel</a>
   <br />
   <cite>www.citibank.co.in/<b>CreditCards</b></cite>
</li>

Из этого html мне нужно извлечь строки, предшествующие тегу

line1: Получить карту Ситибанка IndianOil.Применить сейчас!

line2: получите 10-кратное вознаграждение за покупки - сэкономьте более 5% на топливе

как это должно было бы быть в python?

Ответы [ 4 ]

4 голосов
/ 09 января 2012

Я думаю, вы просто просили строку перед каждым <br/>.

Этот следующий код сделает это для предоставленного вами образца, вычеркнув теги <b> и <a> и напечатав .tail каждого элемента, following-sibling которого равен <br/>.

from lxml import etree

doc = etree.HTML("""
<li class="taf"><h3><a href="26eOfferCode%3DGSONESTP-----------" id="pa1">
    Citibank <b>Credit Card</b> - Save over 5% on fuel | Citibank.co.in</a>
   </h3>Get the IndianOil Citibank <b>Card</b>. Apply Now! 
   <br />
   <a href="e%253DGOOGLE ------">Get 10X Rewards On Shopping</a> -
   <a href="S%2526eOfferCode%253DGSCCSLEX ------">Save Over 5% On Fuel</a>
   <br />
   <cite>www.citibank.co.in/<b>CreditCards</b></cite>
</li>""")

etree.strip_tags(doc,'a','b')

for element in doc.xpath('//*[following-sibling::*[name()="br"]]'):
  print repr(element.tail.strip())

Урожайность:

'Get the IndianOil Citibank Card. Apply Now!'
'Get 10X Rewards On Shopping -\n   Save Over 5% On Fuel'
1 голос
/ 09 января 2012

Как и при любом разборе HTML, вам необходимо сделать некоторые предположения относительно формата HTML.Если мы можем предположить, что предыдущая строка - это все до тега <br> до тега уровня блока или другого <br>, то мы можем сделать следующее ...

from BeautifulSoup import BeautifulSoup

doc = """
   <li class="taf"><h3><a href="26eOfferCode%3DGSONESTP-----------" id="pa1">
    Citibank <b>Credit Card</b> - Save over 5% on fuel | Citibank.co.in</a>
    </h3>Get the IndianOil Citibank <b>Card</b>. Apply Now!
    <br />
    <a href="e%253DGOOGLE ------">Get 10X Rewards On Shopping</a> -
    <a href="S%2526eOfferCode%253DGSCCSLEX ------">Save Over 5% On Fuel</a>
    <br />
    <cite>www.citibank.co.in/<b>CreditCards</b></cite>
</li>
"""

soup = BeautifulSoup(doc)

Теперь мы проанализировалиHTML, затем мы определяем список тегов, которые мы не хотим рассматривать как часть строки.На самом деле есть и другие теги блоков, но это относится и к этому HTML.

block_tags = ["div", "p", "h1", "h2", "h3", "h4", "h5", "h6", "br"]

Мы перебираем каждый тег <br>, возвращаясь назад к его братьям и сестрам, пока у нас не останется больше или пока мы не достигнем тега уровня блока,Каждый раз, когда мы выполняем цикл, мы добавляем узел в начало нашей строки.NavigableStrings не имеет атрибутов name, но мы хотим включить их, следовательно, тест из двух частей в цикле while.

for node in soup.findAll("br"):
    line = ""
    sibling = node.previousSibling
    while sibling is not None and (not hasattr(sibling, "name") or sibling.name not in block_tags):
        line = unicode(sibling) + line
        sibling = sibling.previousSibling
    print line
1 голос
/ 09 января 2012

Решение без ретрансляции на <br> теги:

import lxml.html

html = "..."
tree = lxml.html.fromstring(html)
line1 = ''.join(tree.xpath('//li[@class="taf"]/text() | b/text()')[:3]).strip()
line2 = ' - '.join(tree.xpath('//li[@class="taf"]//a[not(@id)]/text()'))
0 голосов
/ 09 января 2012

Я не знаю, хотите ли вы использовать lxml или красивый суп.Но для lxml с использованием xpath приведен пример

import lxml
from lxml import etree
import urllib2

response = urllib2.urlopen('your url here')
html = response.read()
imdb = etree.HTML(html)
titles = imdb.xpath('/html/body/li/a/text()')//xpath for "line 2" data.[use firebug]

Я использовал xpath для вашего данного фрагмента HTML.Может измениться в исходном контексте.

Вы также можете попробовать cssselect in lxml.

import lxml.html
import urllib
data = urllib.urlopen('your url').read() 
doc = lxml.html.fromstring(data)
elements = doc.cssselect('your csspath here') // CSSpath[using firebug extension]
for element in elements:
      print element.text_content() 
...