本次主要介绍,无论使用的xpath表达式中是否包含text()方法,最后都可以获取目标标签下的文本。使用的依然是etree.HTML和etree.tostring方法。
1.思路
首先将字符串源码转换成_Element对象,然后使用_Element对象的xpath()方法解析xpath表达式。如果通过xpath表达式解析得到的是文本对象,那么先将文本对象(也是字符串)转换成_Element对象,最后通过etree.tostring方法获取_Element对象中的文本内容(可以参考这里)。
2.代码实现
代码如下:
# encoding=utf8
from lxml import etree
def to_text(string, expr):
elements = etree.HTML(string)
data = elements.xpath(expr)[0]
if isinstance(data, str):
data = data.strip()
if not data:
return None
data = etree.HTML(data)
return etree.tostring(data, method='text').strip()
html = '''
<h1>12345</h1>
<script>js</script>
<h2>
<a id="1223" target="_blank" href="test">This is a test</a>
</h2>'''
print to_text(html, '//h1')
print '-' * 20
print to_text(html, '//h2')
print '-' * 20
print to_text(html, '//a')
print '-' * 20
print to_text(html, '//a/text()')
print '-' * 20
print to_text(html, '//script')
print '-' * 20
运行结果:
12345
--------------------
This is a test
--------------------
This is a test
--------------------
This is a test
--------------------
js
--------------------
3.注意事项
当xpath表达式中使用//text()的时候,上面的方法可能就不适用了,因为//text()找到的文本节点有多个。在上面的例子中,找到的第一个节点是一个换行符和制表符的组合,这也是为什么to_text函数中会对data.strip()做判断和处理。在to_text函数中print一下就能明白了:
# encoding=utf8
from lxml import etree
def to_text(string, expr):
elements = etree.HTML(string)
data = elements.xpath(expr)[0]
if isinstance(data, str):
print 'data is: ', repr(data)
data = data.strip()
if not data:
return None
data = etree.HTML(data)
return etree.tostring(data, method='text').strip()
html = '''
<h1>12345</h1>
<script>js</script>
<h2>
<a id="1223" target="_blank" href="test">This is a test</a>
</h2>'''
result = to_text(html, '//h2//text()')
print 'result: ', result
运行结果:
data is: '\n\t\t\t'
result: None