lxml 及 HtmlElement

.attrib 属性和 .get()方法

前者是html tag的属性集合,以字典表示;后者是取得某个属性的值,相当于字典的.get()方法。看示例:

In [35]: doc = lxml.html.fromstring('

abclink

') In [37]: doc.attrib Out[37]: {'class': 'post', 'id': '123'} In [38]: doc.get('class') Out[38]: 'post'
.drop_tag()方法

移除该html tag,但保留它的子节点和文本并合并到该tag的父节点。

In [46]: doc = lxml.html.fromstring('

abclink

') In [47]: doc.find('.//p').drop_tag() In [48]: lxml.html.tostring(doc) Out[48]: b'
abclink
'
.drop_tree()方法   ('.//p')

移除该节及其子节点和文本,而它后面的文本(tail text)合并到前面一个节点或父节点。

In [50]: doc = lxml.html.fromstring('

abclink

') In [51]: doc.find('.//p').drop_tree() In [52]: lxml.html.tostring(doc) Out[52]: b'
'
.drop_tree()方法

移除该节及其子节点和文本,而它后面的文本(tail text)合并到前面一个节点或父节点。

In [50]: doc = lxml.html.fromstring('

abclink

') In [51]: doc.find('.//p').drop_tree() In [52]: lxml.html.tostring(doc) Out[52]: b'
'
通过path(Xpath)或tag查找特定节点,前者返回找到的第一个,第二个返回找到的全部HTMLElement,第三个返回找到的第一个的节点的文本(.text)

In [55]: doc = lxml.html.fromstring('

abclink

') In [56]: doc.find('p') Out[56]: In [57]: doc.find('.//a') Out[57]: In [58]: doc.findall('p') Out[58]: [] In [76]: doc.findtext('.//a') Out[76]: 'link'
.find_class(class_name)方法

通过class名称查找所有含有class_name的元素,返回HtmlElement的列表

In [70]: doc = lxml.html.fromstring('

abclink

') In [71]: doc.find_class('para') Out[71]: [, ]
.get_element_by_id(id) 方法

得到第一个id为输入id的节点。如果有多个相同id的节点(按道理讲,一个HTML文档里面的id是唯一的)只返回第一个。

In [79]: doc = lxml.html.fromstring('

abclink

') In [80]: doc.get_element_by_id('123') Out[80]:
.getchildren()、getparent() 方法

顾名思义,获取 孩子节点和父节点。需要注意的是,还是可以有多个(返回list),父亲只有一个。

In [83]: doc = lxml.html.fromstring('

abclink

') In [84]: doc.getchildren() Out[84]: [] In [85]: doc.getparent() Out[85]: # 注意:输入的本没有body,div已经是最上层节点,它的父节点就是body了
.getnext() .getprevious() 方法

获取后一个或前一个节点,如果没有则返回None。

In [109]: doc = lxml.html.fromstring('

abc

xyz

') In [110]: doc.getnext() In [111]: doc.find('p').getnext() Out[111]: In [112]: doc.find('p').getprevious()
.getiterator()、.iter() 方法

从该节点开始,按文档顺序(深度优先)遍历所有子节点。可以指定只遍历某些tag。

In [127]: doc = lxml.html.fromstring('

abclink

') In [128]: for itr in doc.getiterator(): ...: print(itr.tag) ...: div p a In [129]: for itr in doc.iter(): ...: print(itr.tag) ...: div p a
.iterchildren() 方法

只遍历子节点。

.iterancestors() .iterdescendants()方法

前者遍历前辈(从父亲节点开始),后者遍历后辈(从子辈开始),都跳过该节点。

In [134]: doc = lxml.html.fromstring('

abclink

') In [135]: a = doc.find('.//a') In [136]: for itr in doc.iterancestors(): ...: print(itr.tag) ...: body html In [137]: for itr in a.iterancestors(): ...: print(itr.tag) ...: p div body html In [138]: for itr in doc.iterdescendants(): ...: print(itr.tag) ...: p a
.iterfind(path) 方法

遍历所有符合path的子节点,类似于findall()
.make_links_absolute(base_url)

很多网页的链接都是类似href=”/path/a.html”没有写全网址,这个方法的作用就是补全网址。
.tag 属性

该节点的html tag 名称
.text  and  .tail 属性

都是该节点的文本内容,不同的是一个在tag内,一个在尾部:

text

tail 再看下面的代码 In [173]: doc = lxml.html.fromstring('

abclinkworod

apple
') In [174]: p = doc.find('p') In [175]: p.text Out[175]: 'abc' In [176]: p.tail Out[176]: 'apple'
.text_content() 方法

返回给节点及其子节点包含的所有文本

In [178]: doc.text_content()
Out[178]: 'abclinkworodapple'
lxml.html 从html字符串生成文档树结构

我们下载得到的网页就是一串html字符串,如何把它输入给lxml.html模块,从而生成html文档的树结构呢?
该模块提供了几种不同的方法:

parse(filename_url_or_file):
输入的是一个文件名、URL或文件对象(有read()方法)。
document_fromstring(string):
输入的是一个html的字符串,创建一个HTML文档树结构,它的根节点就是, 和 子节点。
fragment_fromstring(string, create_parent=False):
返回输入字符串的HTML片段。这个片段壁纸只含有一个element(元素),也就是单一节点,除非给出了create_parent 参数,否则会报错。
fragments_fromstring(string):
返回包含输入字符串中所有片段的列表。
fromstring(string):
返回值依据输入字符串而定,如果输入看起来像是一个文档,则返回document_fromstring(string),如果是一个单一片段,则返回fragment_fromstring(string)。
下面我们通过具体示例来说明上面几个方法的不同。

document_fromstring 的使用方法

In [1]: import lxml.html  as lh

In [2]: z = lh.document_fromstring('abcxyz')
# 可以看到,它自动加了根节点
In [3]: z
Out[3]: 

In [4]: z.tag
Out[4]: 'html'
# 还加了节点
In [5]: z.getchildren()
Out[5]: []
# 把字符串的两个节点放在了里面
In [6]: z.getchildren()[0].getchildren()
Out[6]: [, ]
fragment_fromstring 的使用

In [11]: z = lh.fragment_fromstring(‘
abc
xyz
’) --------------------------------------------------------------------------- ParserError Traceback (most recent call last) in () ----> 1 z = lh.fragment_fromstring(‘
abc
xyz
’) ~/.virtualenvs/py3.6/lib/python3.6/site-packages/lxml/html/__init__.py in fragment_fromstring(html, create_parent, base_url, parser, **kw) 850 raise etree.ParserError( 851 “Multiple elements found (%s)” --> 852 % ‘, ‘.join([_element_name(e) for e in elements])) 853 el = elements[0] 854 if el.tail and el.tail.strip(): ParserError: Multiple elements found (div, div) # 可以看到,输入是两个节点(element)时就会报错 # 如果加上 create_parent 参数,就没问题了 In [12]: z = lh.fragment_fromstring('
abc
xyz
', create_parent='p') In [13]: z.tag Out[13]: 'p' In [14]: z.getchildren() Out[14]: [, ] fragments_fromstring 的使用 # 输入字符串含有一个节点,则返回包含这一个节点的列表 In [17]: lh.fragments_fromstring('
abc
') Out[17]: [] # 输入字符串含有多个节点,则返回包含这多个节点的列表 In [18]: lh.fragments_fromstring('
abc
xyz
') Out[18]: [, ] fromstring 的使用 In [27]: z = lh.fromstring('
abc
xyz
') In [28]: z Out[28]: In [29]: z.getchildren() Out[29]: [, ] In [30]: type(z) Out[30]: lxml.html.HtmlElement 这里,fromstring输入的如果是多个节点,它会给加一个父节点并返回。但是像html网页都是从节点开始的,我们使用fromstring() 和 document_fromstring() 都可以得到完整的网页结构。 从上面代码中我们可以看到,那几个函数返回的都是HtmlElement对象

from : https://www.yuanrenxue.com/crawler/extract-data-lxml-xpath.html

你可能感兴趣的:(lxml 及 HtmlElement)