2012-01-09 70 views
0

标签这是我的HTML树如何分割从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> 

从这个网站,我需要提取beforeth的< BR>标签

线路1线:获得印度石油公司花旗银行卡。现在申请!

线路2:获取10X奖励安商场 - 节省超过5%的燃油

它是如何应该在Python呢?

+0

如果这不是唯一的情况,你需要做更多这样的东西,看看一些(x)的HTML解析库。例如[美丽的汤](http://www.crummy.com/software/BeautifulSoup/)或[lxml](http://lxml.de/)。在标准库中,有[minidom](http://docs.python.org/library/xml.dom.minidom.html),但我不喜欢它,它可能不会在错误的语法(你在现实世界中会发现很多)。 – rplnt 2012-01-09 12:28:28

回答

4

我觉得你刚才问的每个<br/>前行。

这下面的代码将做到这一点对您所提供的样品,通过条带化出<b><a>标签和打印每个元素,其following-sibling<br/>.tail

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

'doc。xpath('// * [following-sibling :: br]')'也会工作(没有'name()=“br”')。 – reclosedev 2012-01-09 12:48:06

+0

我同意这个表达。大多数情况下,我都是为了上述表达方式:“”获取印度石油公司的花旗银行卡。现在申请!无 - 无“” – Nava 2012-01-09 14:04:38

0

我不知道你是否想用lxml或美丽的汤。但对于使用XPath这里lxml的是一个例子

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() 
1

解决方案,而中继上<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()')) 
1

与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做的。通过每个<br>标签通过它的兄弟姐妹退一步,直到我们要么没有更多的,还是我们打块级别标记

block_tags = ["div", "p", "h1", "h2", "h3", "h4", "h5", "h6", "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