Python 从html检索尾部文本

Python 从html检索尾部文本,python,xpath,lxml,Python,Xpath,Lxml,使用lxml的python2.7 我有一些令人烦恼的html格式,如下所示: <td> <b>"John" </b> <br> "123 Main st. " <br> "New York " <b> "Sally" </b> <br> "101 California St. " <br> "San Francisco " </td> “约翰” “主街123号。 " “

使用lxml的python2.7

我有一些令人烦恼的html格式,如下所示:

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

“约翰”

“主街123号。 "
“纽约 " “莎莉”
“加利福尼亚街101号。 "
“旧金山 "
所以基本上它是一个单一的td,里面有很多东西。我正试图整理一份名单或是一份姓名和地址的记录

到目前为止,我所做的是使用
tree.xpath('//td/b')
获得一个具有名称的节点列表。假设我现在在John的
b
节点上


我正在尝试为当前节点之后但下一个
b
节点(Sally)之前的所有内容获取
whater.xpath('string()')
。我尝试了一系列不同的xpath查询,但似乎都做不好。特别是,每当我在没有
[]
括号的表达式中使用
运算符时,它都会返回一个bool,而不是满足条件的所有节点的列表。有人能帮忙吗?

从每个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()
注意:如果要获取某些非关闭html标记的文本,例如,

,则应使用
tag.tail

希望这会有所帮助。

这应该可以:

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
此代码打印:

{'"John"': '"123 Main st."', '"Sally"': '"101 California St."'}
(您可能希望去掉引号!)


不必使用xpath,您可以使用lxml的一个解析器来轻松浏览HTML。解析器将把HTML文档转换为“etree”,您可以使用提供的方法导航它。lxml模块提供了一个名为
iter()
的方法,该方法允许您传入标记名并接收树中具有该名称的所有元素。在您的情况下,如果您使用它来获取所有
元素,那么您可以手动导航到

元素并检索包含所需信息的尾部文本。您可以在

的“Elements contain text”(元素包含文本)标题中找到这方面的信息,因为筛选符合表达式的元素是方括号所做的事情,您为什么不希望使用它们(假设您的
正在向表达式添加条件,这就是它的用途)?您是否可以展示您尝试过的内容,特别是您如何尝试使用
?…您当前的答案就其本身而言是不错的,但它们不太可能帮助在座的人解决您在标题中提出的相同问题(尝试对XPath查询应用多个条件);如果您添加了更多信息,应该可以回答这个名义上的问题。相比之下,如果你不感兴趣的话,你可以考虑编辑标题标题,以更好地反映你真正关心的内容。我也建议更改标题,也许类似于“从HTML中检索尾文本”,因为这是问题的核心所在。不知怎的,我从来没有学过如何处理休息的
tail
,但它太神奇了!谢谢没问题,老实说,我自己才知道!因为我每天都在工作中使用XML,所以这对我来说也是一次很好的学习经历。
{'"John"': '"123 Main st."', '"Sally"': '"101 California St."'}