abclink
.attrib 属性和 .get()方法
前者是html tag的属性集合,以字典表示;后者是取得某个属性的值,相当于字典的.get()方法。看示例:
In [35]: doc = lxml.html.fromstring('')
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(‘abcxyz’)
---------------------------------------------------------------------------
ParserError Traceback (most recent call last)
in ()
----> 1 z = lh.fragment_fromstring(‘abcxyz’)
~/.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('abcxyz', 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('abcxyz')
Out[18]: [, ]
fromstring 的使用
In [27]: z = lh.fromstring('abcxyz')
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