从html中检索尾部文本

时间:2016-09-20 18:45:02

标签: python xpath lxml

Python 2.7使用lxml

我有一些令人讨厌的html,看起来像这样:

<td>
<b>"John"
</b>
<br>
"123 Main st.
"
<br>
"New York
"
<b>
"Sally"
</b>
<br>
"101 California St.
"
<br>
"San Francisco
"
</td>

所以基本上它是一个单一的td,里面有很多东西。我正在尝试编制名单及其地址的列表或词典。

到目前为止,我所做的是使用tree.xpath('//td/b')获取名称的节点列表。因此,我们假设我目前在约翰的b节点上。

我试图在当前节点之后但在下一个whatever.xpath('string()')节点(Sally)之前获取b。我尝试过一系列不同的xpath查询,但似乎无法做到这一点。特别是,每当我在没有and括号的表达式中使用[]运算符时,它返回bool而不是满足条件的所有节点的列表。任何人都可以帮忙吗?

2 个答案:

答案 0 :(得分:1)

这应该有效:

//# declare variables outside of function (make once & re-use) 
var searchtext:String = "";
var index:int = 0; 

//# after updating searchtext string with user-text then run function below

function fl_MouseClickHandler_4(event:MouseEvent):void
{
    searchtext = searchtext.text.toLowerCase();
    index = names.indexOf(searchtext); //test with "holy spirit"

    if(index == -1)
    {
        trace("index is : -1 : No match found");
        //do something when frame not found
    }
    else
    {
        trace("index is : " + index + " ::: result is : " + (frames[index]) );
        gotoAndStop( frames[index] );
    }
}

此代码打印:

from lxml import etree

p = etree.HTMLParser()
html = open(r'./test.html','r')
data = html.read()
tree = etree.fromstring(data, p)

my_dict = {}

for b in tree.iter('b'):
    br = b.getnext().tail.replace('\n', '')
    my_dict[b.text.replace('\n', '')] = br

print my_dict

(您可能想要删除引号!)

您可以使用lxml的解析器之一来轻松导航HTML,而不是使用xpath。解析器将HTML文档转换为“etree”,您可以使用提供的方法进行导航。 lxml模块提供了一个名为{'"John"': '"123 Main st."', '"Sally"': '"101 California St."'} 的方法,它允许您传入标记名称并接收树中具有该名称的所有元素。在您的情况下,如果您使用它来获取所有iter()元素,则可以手动导航到<b>元素并检索其尾部文本,其中包含您需要的信息。您可以在lxml.etree tutorial.

的“Elements contains text”标题中找到有关此内容的相关信息

答案 1 :(得分:0)

从每个td的视图中不使用getchildren函数。例如:

from lxml import html

s = """
<td>
<b>"John"
</b>
<br>
"123 Main st.
"
<br>
"New York
"
<b>
"Sally"
</b>
<br>
"101 California St.
"
<br>
"San Francisco
"
</td>
"""

records = []
cur_record = -1
cur_field = 1

FIELD_NAME = 0
FIELD_STREET = 1
FIELD_CITY = 2

doc = html.fromstring(s)
td = doc.xpath('//td')[0]
for child in td.getchildren():
    if child.tag == 'b':
        cur_record += 1
        record = dict()
        record['name'] = child.text.strip()
        records.append(record)
        cur_field = 1
    elif child.tag == 'br':
        if cur_field == FIELD_STREET:
            records[cur_record]['street'] = child.tail.strip()
            cur_field += 1
        elif cur_field == FIELD_CITY:
            records[cur_record]['city'] = child.tail.strip()

结果是:

records = [
           {'city': '"New York\n"', 'name': '"John"\n', 'street': '"123 Main st.\n"'},
           {'city': '"San Francisco\n"', 'name': '\n"Sally"\n', 'street': '"101 California St.\n"'}
          ]

请注意,如果您想获取某些非近似html标记的文字,请使用tag.tail,例如<br>

希望这会有所帮助。