3.解析模块的使用
推荐使用pyquery
Beautiful Soup
安装
pip install bs4
或者
pip install beautifulsoup4
用途
BeautifulSoup
就是 Python 的一个 HTML 或 XML
的解析库,我们可以用它来方便地从网页中提取数据
解析器比较
BeautifulSoup 支持的解析器及优缺点
Python标准库
BeautifulSoup(markup, "html.parser")
Python的内置标准库、执行速度适中 、文档容错能力强
Python 2.7.3 or 3.2.2)前的版本中文容错能力差
LXML HTML 解析器
BeautifulSoup(markup, "lxml")
速度快、文档容错能力强
需要安装C语言库
LXML XML 解析器
BeautifulSoup(markup, "xml")
速度快、唯一支持XML的解析器
需要安装C语言库
html5lib
BeautifulSoup(markup, "html5lib")
最好的容错性、以浏览器的方式解析文档、生成 HTML5 格式的文档
速度慢、不依赖外部扩展
文档
用法
简单用例
样本
html = """
<html><head><title>The Dormouse's story</title></head>
<body>
<p class="title" name="dromouse"><b>The Dormouse's story</b></p>
<p class="story">Once upon a time there were three little sisters; and their names were
<a href="http://example.com/elsie" class="sister" id="link1"><!-- Elsie --></a>,
<a href="http://example.com/lacie" class="sister" id="link2">Lacie</a> and
<a href="http://example.com/tillie" class="sister" id="link3">Tillie</a>;
and they lived at the bottom of a well.</p>
<p class="story">...</p>
"""
导入模块
from bs4 import BeautifulSoup
解析数据
soup = BeautifulSoup(html,'lxml') # 第一个参数为传入的文本或者网页内容,第二个参数为解 # 析器
print(soup.prettify()) # .prettify():把要解析的字符串以标准的缩进格式输出
print(soup.title.string) # .title.string:选择HTML中的title节点
# 再调用string属性得到里面的文本
运行结果:

节点选择器
选择元素
实例:
html = """
<html><head><title>The Dormouse's story</title></head>
<body>
<p class="title" name="dromouse"><b>The Dormouse's story</b></p>
<p class="story">Once upon a time there were three little sisters; and their names were
<a href="http://example.com/elsie" class="sister" id="link1"><!-- Elsie --></a>,
<a href="http://example.com/lacie" class="sister" id="link2">Lacie</a> and
<a href="http://example.com/tillie" class="sister" id="link3">Tillie</a>;
and they lived at the bottom of a well.</p>
<p class="story">...</p>
"""
from bs4 import BeautifulSoup
soup = BeautifulSoup(html, 'lxml')
print(soup.title)
print(type(soup.title))
print(soup.title.string)
print(soup.head)
# 只能选择第一个p节点
print(soup.p)
运行结果:
<title>The Dormouse's story</title>
<class 'bs4.element.Tag'>
The Dormouse's story
<head><title>The Dormouse's story</title></head>
<p class="title" name="dromouse"><b>The Dormouse's story</b></p>
提取信息
获取名称
可以利用 name
属性来获取节点的名称
实例:选择title,调用name属性得到节点的名称
print(soup.title.name)
运行结果:
title
获取属性
调用 attrs 获取所有属性
# 返回字典
print(soup.p.attrs)
print(soup.p.attrs['name'])
运行结果:
{'class': ['title'], 'name': 'dromouse'}
dromouse
获取内容
利用 string 属性获取节点元素包含的文本内容
print(soup.p.string)
运行结果:
The Dormouse's story
嵌套选择
实例:获取head节点内部的title节点
html = """
<html><head><title>The Dormouse's story</title></head>
<body>
"""
from bs4 import BeautifulSoup
soup = BeautifulSoup(html, 'lxml')
print(soup.head.title)
print(type(soup.head.title))
print(soup.head.title.string)
运行结果:
<title>The Dormouse's story</title>
<class 'bs4.element.Tag'>
The Dormouse's story
关联选择
子节点和子孙节点
获取直接子节点可以调用 contents 属性
实例:获取body节点下子节点p
html = """
<html>
<head>
<title>The Dormouse's story</title>
</head>
<body>
<p class="story">
Once upon a time there were three little sisters; and their names were
<a href="http://example.com/elsie" class="sister" id="link1">
<span>Elsie</span>
</a>
<a href="http://example.com/lacie" class="sister" id="link2">Lacie</a>
and
<a href="http://example.com/tillie" class="sister" id="link3">Tillie</a>
and they lived at the bottom of a well.
</p>
<p class="story">...</p>
"""
from bs4 import BeautifulSoup
soup = BeautifulSoup(html,'lxml')
print(soup.body.contents)
运行结果:返回结果是列表形式
['\n', <p class="story">
Once upon a time there were three little sisters; and their names were
<a class="sister" href="http://example.com/elsie" id="link1">
<span>Elsie</span>
</a>
<a class="sister" href="http://example.com/lacie" id="link2">Lacie</a>
and
<a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>
and they lived at the bottom of a well.
</p>, '\n', <p class="story">...</p>, '\n']
可以调用 children 属性,得到相应的结果:
from bs4 import BeautifulSoup
soup = BeautifulSoup(html,'lxml')
print(soup.body.children)
for i,child in enumerate(soup.body.children):
print(i,child)
运行结果:
<list_iterator object at 0x00000217D33CD048>0
1 <p class="story"> Once upon a time there were three little sisters; and their names were <a class="sister" href="http://example.com/elsie" id="link1"><span>Elsie</span></a><a class="sister" href="http://example.com/lacie" id="link2">Lacie</a> and <a class="sister" href="http://example.com/tillie" id="link3">Tillie</a> and they lived at the bottom of a well. </p>2
3 <p class="story">...</p>4
要得到所有的子孙节点的话可以调用 descendants 属性
from bs4 import BeautifulSoup
soup = BeautifulSoup(html,'lxml')
print(soup.body.descendants)
for i,child in enumerate(soup.body.descendants):
print(i,child)
运行结果:
<generator object descendants at 0x0000014D106353B8>0
1 <p class="story"> Once upon a time there were
...
父节点和祖先节点
要获取某个节点元素的父节点,可以调用 parent 属性:
实例:获取节点a的父节点p下的内容
html = """
<html>
<head>
<title>The Dormouse's story</title>
</head>
<body>
<p class="story">
Once upon a time there were three little sisters; and their names were
<a href="http://example.com/elsie" class="sister" id="link1">
<span>Elsie</span>
</a>
</p>
<p class="story">...</p>
"""
from bs4 import BeautifulSoup
soup = BeautifulSoup(html,'lxml')
print(soup.a.parent)
运行结果:
<p class="story">
Once upon a time there were three little sisters; and their names were
<a class="sister" href="http://example.com/elsie" id="link1">
<span>Elsie</span>
</a>
</p>
要想获取所有的祖先节点,可以调用 parents 属性
html = """
<html>
<body>
<p class="story">
<a href="http://example.com/elsie" class="sister" id="link1">
<span>Elsie</span>
</a>
</p>
"""
from bs4 import BeautifulSoup
soup = BeautifulSoup(html,'lxml')
print(type(soup.a.parents))
print(list(enumerate(soup.a.parents)))
运行结果:
<class 'generator'>
[(0, <p class="story">
<a class="sister" href="http://example.com/elsie"
...
兄弟节点
next_sibling :获取节点的下一个兄弟节点
previous_sibling:获取节点上一个兄弟节点
next_siblings :返回所有前面兄弟节点的生成器
previous_siblings :返回所有后面的兄弟节点的生成器
实例:
html = """
<html>
<body>
<p class="story">
Once upon a time there were three little sisters; and their names were
<a href="http://example.com/elsie" class="sister" id="link1">
<span>Elsie</span>
</a>
Hello
<a href="http://example.com/lacie" class="sister" id="link2">Lacie</a>
and
<a href="http://example.com/tillie" class="sister" id="link3">Tillie</a>
and they lived at the bottom of a well.
</p>
"""
from bs4 import BeautifulSoup
soup = BeautifulSoup(html,'lxml')
print('next sibling:',soup.a.next_sibling)
print('previous sibling:',soup.a.previous_sibling)
print("next siblings:",list(soup.a.next_siblings))
print("previouos siblings:",list(soup.a.previous_siblings))
运行结果:
next sibling:
Hello
...
提取信息
获取一些信息,比如文本、属性等等
html = """
<html>
<body>
<p class="story">
Once upon a time there were three little sisters; and their names were
<a href="http://example.com/elsie" class="sister" id="link1">Bob</a><a href="http://example.com/lacie" class="sister" id="link2">Lacie</a>
</p>
"""
from bs4 import BeautifulSoup
soup = BeautifulSoup(html, 'lxml')
print('Next Sibling:')
print(type(soup.a.next_sibling))
print(soup.a.next_sibling)
print(soup.a.next_sibling.string)
print('Parent:')
print(type(soup.a.parents))
print(list(soup.a.parents)[0])
print(list(soup.a.parents)[0].attrs['class'])
运行结果:
Next Sibling:
<class 'bs4.element.Tag'>
...
方法选择器
常用查询方法:find_all()、find()
find_all()
查询所有符合条件的元素
语法:
find_all(name , attrs , recursive , text , **kwargs)
name
根据节点名来查询元素
html='''
<div class="panel">
<div class="panel-heading">
<h4>Hello</h4>
</div>
<div class="panel-body">
<ul class="list" id="list-1">
<li class="element">Foo</li>
<li class="element">Bar</li>
<li class="element">Jay</li>
</ul>
<ul class="list list-small" id="list-2">
<li class="element">Foo</li>
<li class="element">Bar</li>
</ul>
</div>
</div>
'''
from bs4 import BeautifulSoup
soup = BeautifulSoup(html,'lxml')
print(soup.find_all(name='ul'))
print(type(soup.find_all(name='ul')[0]))
运行结果:返回结果类型为:bs4.element.Tag
[<ul class="list" id="list-1">
<li class="element">Foo</li>
...
获取ul下的li节点以及li下的文本内容
from bs4 import BeautifulSoup
soup = BeautifulSoup(html,'lxml')
# print(soup.find_all(name='ul'))
# print(type(soup.find_all(name='ul')[0]))
for ul in soup.find_all(name='ul'):
print(ul.find_all(name='li'))
for li in ul.find_all(name='li'):
print(li.string)
运行结果:
[<li class="element">Foo</li>, <li class="element">Bar</li>, <li class="element">Jay</li>]
....
attrs
根据属性来进行查询
html='''
<div class="panel">
<div class="panel-heading">
<h4>Hello</h4>
</div>
<div class="panel-body">
<ul class="list" id="list-1" name="elements">
<li class="element">Foo</li>
<li class="element">Bar</li>
<li class="element">Jay</li>
</ul>
<ul class="list list-small" id="list-2">
<li class="element">Foo</li>
<li class="element">Bar</li>
</ul>
</div>
</div>
'''
from bs4 import BeautifulSoup
soup = BeautifulSoup(html,'lxml')
# 查询属性以字典的的进行查询
print(soup.find_all(attrs={'id':'list-1'}))
print(soup.find_all(attrs={"name":"elements"}))
运行结果:
[<ul class="list" id="list-1" name="elements">
<li class="element">Foo</li>
...
对于常用的属性比如id,class,可以不用attrs传递
from bs4 import BeautifulSoup
soup = BeautifulSoup(html, 'lxml')
print(soup.find_all(id='list-1'))
# 由于class是关键字需要添加下划线区分
print(soup.find_all(class_='element'))
运行结果:
[<ul class="list" id="list-1">
<li class="element">Foo</li>
<li class="element">Bar</li>
<li class="element">Jay</li>
</ul>]
[<li class="element">Foo</li>, <li class="element">Bar</li>, <li class="element">Jay</li>, <li class="element">Foo</li>, <li class="element">Bar</li>]
text
text 参数可以用来匹配节点的文本,传入的形式可以是字符串,可以是正则表达式对象
html='''
<div class="panel">
<div class="panel-body">
<a>Hello, this is a link</a>
<a>Hello, this is a link, too</a>
</div>
</div>
'''
import re
from bs4 import BeautifulSoup
soup = BeautifulSoup(html,'lxml')
# 查询文本包含有link的文本
print(soup.find_all(text=re.compile('link')))
运行结果:
['Hello, this is a link', 'Hello, this is a link, too']
find()
find() 方法返回的是单个元素,即第一个匹配的元素,而 find_all() 返回的是所有匹配的元素组成的列表
html='''
<div class="panel">
<div class="panel-body">
<a class='element'>Hello, this is a link</a>
<a class='element'>Hello, this is a link, too</a>
</div>
</div>
'''
from bs4 import BeautifulSoup
soup = BeautifulSoup(html,'lxml')
print(soup.find(name='a'))
print(soup.find(attrs={'class':'element'}))
print(soup.find(class_='element'))
print(type(soup.find(name='a')))
返回结果:返回类型为<class 'bs4.element.Tag'>
<a class="element">Hello, this is a link</a>
<a class="element">Hello, this is a link</a>
<a class="element">Hello, this is a link</a>
<class 'bs4.element.Tag'>
其他查询方法
find_parents() find_parent()
find_parents() 返回所有祖先节点,find_parent() 返回直接父节点。
find_next_siblings() find_next_sibling()
find_next_siblings() 返回后面所有兄弟节点,find_next_sibling() 返回后面第一个兄弟节点。
find_previous_siblings() find_previous_sibling()
find_previous_siblings() 返回前面所有兄弟节点,find_previous_sibling() 返回前面第一个兄弟节点。
find_all_next() find_next()
find_all_next() 返回节点后所有符合条件的节点, find_next() 返回第一个符合条件的节点。
find_all_previous() 和 find_previous()
find_all_previous() 返回节点后所有符合条件的节点, find_previous() 返回第一个符合条件的节点
CSS选择器
相关链接:http://www.w3school.com.cn/cssref/css_selectors.asp。
使用 CSS 选择器,只需要调用 select() 方法,传入相应的 CSS 选择器
实例:
html='''
<div class="panel">
<div class="panel-heading">
<h4>Hello</h4>
</div>
<div class="panel-body">
<ul class="list" id="list-1">
<li class="element">Foo</li>
<li class="element">Bar</li>
<li class="element">Jay</li>
</ul>
<ul class="list list-small" id="list-2">
<li class="element">Foo</li>
<li class="element">Bar</li>
</ul>
</div>
</div>
'''
from bs4 import BeautifulSoup
soup = BeautifulSoup(html,'lxml')
print(soup.select('.panel .panel-heading'))
print(soup.select('ul li'))
print(soup.select('#list-2 .element'))
print(soup.select('ul')[0])
运行结果:
[<div class="panel-heading">
<h4>Hello</h4>
</div>]
...
嵌套选择
实例:select() 方法同样支持嵌套选择,例如我们先选择所有 ul 节点,再遍历每个 ul 节点选择其 li 节点
from bs4 import BeautifulSoup
soup = BeautifulSoup(html,'lxml')
for ul in soup.select('ul'):
print(ul.select('li'))
运行结果:
[<li class="element">Foo</li>, <li class="element">Bar</li>, <li class="element">Jay</li>]
[<li class="element">Foo</li>, <li class="element">Bar</li>]
获取属性
获取属性还是可以用上面的方法获取
from bs4 import BeautifulSoup
soup = BeautifulSoup(html,'lxml')
for ul in soup.select('ul'):
print(ul['id'])
print(ul.attrs['id'])
运行结果:
list-1
list-1
list-2
list-2
获取文本
获取文本可以用string 属性,还有一种方法那就是 get_text(),同样可以获取文本值。
from bs4 import BeautifulSoup
soup = BeautifulSoup(html,'lxml')
for li in soup.select('li'):
print('GET TEXT:',li.get_text())
print('STRING:',li.string)
运行结果:
GET TEXT: Foo
STRING: Foo
GET TEXT: Bar
...
细节
推荐使用 LXML 解析库,必要时使用 html.parser
节点选择筛选功能弱但是速度快
建议使用 find()、find_all() 查询匹配单个结果或者多个结果
如果对 CSS 选择器熟悉的话可以使用 select() 选择法
如何匹配规则不是熟练,而且想快速获取,可以如下操作:

右键

Pyquery
安装
pip install pquery
用途
PyQuery
允许像JQuery
一样对快速对xml(lxml)
文档进行元素查询、元素操作的python库。如果熟悉JQuery的api,那么掌握PyQuery是一件十分容易的事情,因为PyQuery的api和JQuery的api基本上一致。PyQuery是一款基于lxml的库,而lxml能够快速处理xml和html文档。
文档
用法
初始化
PyQuery 初始化的时候也需要传入 HTML 数据源来初始化一个操作对象,它的初始化方式有多种,比如直接传入字符串,传入 URL,传文件名
字符串初始化
html = '''
<div>
<ul>
<li class="item-0">first item</li>
<li class="item-1"><a href="link2.html">second item</a></li>
<li class="item-0 active"><a href="link3.html"><span class="bold">third item</span></a></li>
<li class="item-1 active"><a href="link4.html">fourth item</a></li>
<li class="item-0"><a href="link5.html">fifth item</a></li>
</ul>
</div>
'''
from pyquery import PyQuery as pq
doc = pq(html)
print(doc('li')) # 获取li节点
运行结果:
<li class="item-0">first item</li>
<li class="item-1"><a href="link2.html">second item</a></li>
<li class="item-0 active"><a href="link3.html"><span class="bold">third item</span></a></li>
<li class="item-1 active"><a href="link4.html">fourth item</a></li>
<li class="item-0"><a href="link5.html">fifth item</a></li>
url初始化
指定传入的参数为url
from pyquery import PyQuery as pq
doc = pq(url="http://thefoxfairy.gitbook.io/")
print(doc("title"))
运行结果:
<title data-react-helmet="true">Introduction - 112的一员</title>
但是不建议这样做,应该配合请求库一起使用
文件初始化
传入参数指定为 filename
from pyquery import PyQuery as pq
doc = pq(filename='test.html')
print(doc('li'))
CSS选择器
通过css选择器,筛选出所需的数据
from pyquery import PyQuery as pq
html = '''
<div id="container">
<ul class="list">
<li class="item-0">first item</li>
<li class="item-1"><a href="link2.html">second item</a></li>
<li class="item-0 active"><a href="link3.html"><span class="bold">third item</span></a></li>
<li class="item-1 active"><a href="link4.html">fourth item</a></li>
<li class="item-0"><a href="link5.html">fifth item</a></li>
</ul>
</div>
'''
doc = pq(html)
print(doc('#container .list li'))
print(type(doc('#container .list li')))
运行结果:
<li class="item-0">first item</li>
<li class="item-1"><a href="link2.html">second item</a></li>
<li class="item-0 active"><a href="link3.html"><span class="bold">third item</span></a></li>
<li class="item-1 active"><a href="link4.html">fourth item</a></li>
<li class="item-0"><a href="link5.html">fifth item</a></li>
<class 'pyquery.pyquery.PyQuery'>
.class
.intro
选择 class="intro" 的所有元素。
#id
#firstname
选择 id="firstname" 的所有元素。
*
*
选择所有元素。
element
p
选择所有
元素。
element,element
div,p
选择所有元素和所有
元素。
elementelement
div p
选择元素内部的所有
元素。
element>element
div>p
选择父元素为元素的所有
元素。
element+element
div+p
选择紧接在元素之后的所有
元素。
[attribute]
[target]
选择带有 target 属性所有元素。
[attribute=value]
[target=_blank]
选择 target="_blank" 的所有元素。
[attribute~=value]
[title~=flower]
选择 title 属性包含单词 "flower" 的所有元素。
[attribute|=value]
[lang|=en]
选择 lang 属性值以 "en" 开头的所有元素。
:link
a:link
选择所有未被访问的链接。
:visited
a:visited
选择所有已被访问的链接。
:active
a:active
选择活动链接。
:hover
a:hover
选择鼠标指针位于其上的链接。
:focus
input:focus
选择获得焦点的 input 元素。
:first-letter
p:first-letter
选择每个
元素的首字母。
:first-line
p:first-line
选择每个
元素的首行。
:first-child
p:first-child
选择属于父元素的第一个子元素的每个
元素。
:before
p:before
在每个
元素的内容之前插入内容。
:after
p:after
在每个
元素的内容之后插入内容。
:lang(language)
p:lang(it)
选择带有以 "it" 开头的 lang 属性值的每个
元素。
element1~element2
p~ul
选择前面有
元素的每个
元素。
[attribute^=value]
a[src^="https"]
选择其 src 属性值以 "https" 开头的每个 元素。
[attribute$=value]
a[src$=".pdf"]
选择其 src 属性以 ".pdf" 结尾的所有 元素。
[attribute*=value]
a[src*="abc"]
选择其 src 属性中包含 "abc" 子串的每个 元素。
:first-of-type
p:first-of-type
选择属于其父元素的首个
元素的每个
元素。
:last-of-type
p:last-of-type
选择属于其父元素的最后
元素的每个
元素。
:only-of-type
p:only-of-type
选择属于其父元素唯一的
元素的每个
元素。
:only-child
p:only-child
选择属于其父元素的唯一子元素的每个
元素。
:nth-child(n)
p:nth-child(2)
选择属于其父元素的第二个子元素的每个
元素。
:nth-last-child(n)
p:nth-last-child(2)
同上,从最后一个子元素开始计数。
:nth-of-type(n)
p:nth-of-type(2)
选择属于其父元素第二个
元素的每个
元素。
:nth-last-of-type(n)
p:nth-last-of-type(2)
同上,但是从最后一个子元素开始计数。
:last-child
p:last-child
选择属于其父元素最后一个子元素每个
元素。
:root
:root
选择文档的根元素。
:empty
p:empty
选择没有子元素的每个
元素(包括文本节点)。
:target
#news:target
选择当前活动的 #news 元素。
:enabled
input:enabled
选择每个启用的 元素。
:disabled
input:disabled
选择每个禁用的 元素
:checked
input:checked
选择每个被选中的 元素。
:not(selector)
:not(p)
选择非
元素的每个元素。
::selection
::selection
选择被用户选取的元素部分。
查找节点
pyquery的常用的查询函数,这些函数和 jQuery 中的函数用法完全相同
子节点
查找子节点需要用到 find() 方法,传入的参数是 CSS 选择器
from pyquery import PyQuery as pq
doc = pq(html)
items = doc('.list')
print(type(items))
print(items)
list_itmes = items.find('li')
print(type(list_itmes))
print(list_itmes)
运行结果:
<class 'pyquery.pyquery.PyQuery'>
<ul class="list">
<li class="item-0">first item</li>
<li class="item-1"><a href="link2.html">second item</a></li>
<li class="item-0 active"><a href="link3.html"><span class="bold">third item</span></a></li>
<li class="item-1 active"><a href="link4.html">fourth item</a></li>
<li class="item-0"><a href="link5.html">fifth item</a></li>
</ul>
<class 'pyquery.pyquery.PyQuery'>
<li class="item-0">first item</li>
<li class="item-1"><a href="link2.html">second item</a></li>
<li class="item-0 active"><a href="link3.html"><span class="bold">third item</span></a></li>
<li class="item-1 active"><a href="link4.html">fourth item</a></li>
<li class="item-0"><a href="link5.html">fifth item</a></li>()
子孙节点
find() 的查找范围是节点的所有子孙节点,而如果只想查找子节点,那可以用 children() 方法
from pyquery import PyQuery as pq
doc = pq(html)
lis = doc.children()
print(type(lis))
print(lis)
运行结果:
<class 'pyquery.pyquery.PyQuery'>
<ul class="list">
<li class="item-0">first item</li>
<li class="item-1"><a href="link2.html">second item</a></li>
<li class="item-0 active"><a href="link3.html"><span class="bold">third item</span></a></li>
<li class="item-1 active"><a href="link4.html">fourth item</a></li>
<li class="item-0"><a href="link5.html">fifth item</a></li>
</ul>
实例:筛选出子节点class属性值为active
from pyquery import PyQuery as pq
items = pq(html)
lis = items.children('.list .active')
print(type(lis))
print(lis)
运行结果:
<class 'pyquery.pyquery.PyQuery'>
<li class="item-0 active"><a href="link3.html"><span class="bold">third item</span></a></li>
<li class="item-1 active"><a href="link4.html">fourth item</a></li>
父节点
可以用 parent() 方法来获取某个节点的父节点
实例:返回class属性值list当前节点的父节点下的内容
html = '''
<div class="wrap">
<div id="container">
<ul class="list">
<li class="item-0">first item</li>
<li class="item-1"><a href="link2.html">second item</a></li>
<li class="item-0 active"><a href="link3.html"><span class="bold">third item</span></a></li>
<li class="item-1 active"><a href="link4.html">fourth item</a></li>
<li class="item-0"><a href="link5.html">fifth item</a></li>
</ul>
</div>
</div>
'''
from pyquery import PyQuery as pq
doc = pq(html)
items = doc('.list')
container = items.parent()
print(type(container))
print(container)
运行结果:
<class 'pyquery.pyquery.PyQuery'>
<div id="container">
<ul class="list">
<li class="item-0">first item</li>
<li class="item-1"><a href="link2.html">second item</a></li>
<li class="item-0 active"><a href="link3.html"><span class="bold">third item</span></a></li>
<li class="item-1 active"><a href="link4.html">fourth item</a></li>
<li class="item-0"><a href="link5.html">fifth item</a></li>
</ul>
</div>
祖先节点
parents() 方法会返回所有的祖先节点
from pyquery import PyQuery as pq
doc = pq(html)
items = doc('.list')
parents= items.parents()
print(type(parents))
print(parents)
结果会有两个节点
运行结果:
<class 'pyquery.pyquery.PyQuery'>
<div class="wrap">
<div id="container">
<ul class="list">
<li class="item-0">first item</li>
<li class="item-1"><a href="link2.html">second item</a></li>
<li class="item-0 active"><a href="link3.html"><span class="bold">third item</span></a></li>
<li class="item-1 active"><a href="link4.html">fourth item</a></li>
<li class="item-0"><a href="link5.html">fifth item</a></li>
</ul>
</div>
</div><div id="container">
<ul class="list">
<li class="item-0">first item</li>
<li class="item-1"><a href="link2.html">second item</a></li>
<li class="item-0 active"><a href="link3.html"><span class="bold">third item</span></a></li>
<li class="item-1 active"><a href="link4.html">fourth item</a></li>
<li class="item-0"><a href="link5.html">fifth item</a></li>
</ul>
</div>
筛选出指定父节点
实例:筛选出属性值为wrap的父节点
from pyquery import PyQuery as pq
doc = pq(html)
items = doc('.list')
parents = items.parents('.wrap')
print(type(parents))
print(parents)
运行结果:
<class 'pyquery.pyquery.PyQuery'>
<div class="wrap">
<div id="container">
<ul class="list">
<li class="item-0">first item</li>
<li class="item-1"><a href="link2.html">second item</a></li>
<li class="item-0 active"><a href="link3.html"><span class="bold">third item</span></a></li>
<li class="item-1 active"><a href="link4.html">fourth item</a></li>
<li class="item-0"><a href="link5.html">fifth item</a></li>
</ul>
</div>
</div>
兄弟节点
要获取兄弟节点可以使用 siblings() 方法
from pyquery import PyQuery as pq
doc = pq(html)
li = doc('.list .item-0.active')
print(li.siblings())
运行结果:
<li class="item-1"><a href="link2.html">second item</a></li>
<li class="item-0">first item</li>
<li class="item-1 active"><a href="link4.html">fourth item</a></li>
<li class="item-0"><a href="link5.html">fifth item</a></li>
筛选某个指定兄弟节点
from pyquery import PyQuery as pq
doc = pq(html)
li = doc('.list .item-0.active')
print(li.siblings('.active'))
运行结果:
<li class="item-1 active"><a href="link4.html">fourth item</a></li
遍历
对于多个节点的结果,需要遍历来获取了
实例:把每一个 li 节点进行遍历,,需要调用 items() 方法
from pyquery import PyQuery as pq
doc = pq(html)
lis = doc('li').items()
print(type(lis))
for li in lis:
print(li,type(li))
运行结果:
<class 'generator'>
<li class="item-0">first item</li>
<class 'pyquery.pyquery.PyQuery'>
<li class="item-1"><a href="link2.html">second item</a></li>
<class 'pyquery.pyquery.PyQuery'>
<li class="item-0 active"><a href="link3.html"><span class="bold">third item</span></a></li>
<class 'pyquery.pyquery.PyQuery'>
<li class="item-1 active"><a href="link4.html">fourth item</a></li>
<class 'pyquery.pyquery.PyQuery'>
<li class="item-0"><a href="link5.html">fifth item</a></li>
<class 'pyquery.pyquery.PyQuery'>
获取信息
获取属性
获取文本
获取属性
使用attr() 方法获取属性
html = '''
<div class="wrap">
<div id="container">
<ul class="list">
<li class="item-0">first item</li>
<li class="item-1"><a href="link2.html">second item</a></li>
<li class="item-0 active"><a href="link3.html"><span class="bold">third item</span></a></li>
<li class="item-1 active"><a href="link4.html">fourth item</a></li>
<li class="item-0"><a href="link5.html">fifth item</a></li>
</ul>
</div>
</div>
'''
from pyquery import PyQuery as pq
doc = pq(html)
a = doc('.item-0.active a')
print(a,type(a))
print(a.attr('href'))
print(a.attr.href)
有两种获取属性方法:
a.attr('href')
a.attr.href
运行结果:
<a href="link3.html"><span class="bold">third item</span></a> <class 'pyquery.pyquery.PyQuery'>
link3.html
link3.html
当返回结果包含多个节点时,调用 attr() 方法只会得到第一个节点的属性
from pyquery import PyQuery as pq
doc = pq(html)
a = doc('a')
for item in a.items():
print(item.attr('href'))
运行结果:
link2.html
link3.html
link4.html
link5.html
获取文本
调用 text() 方法,就可以获取其内部的文本信息了,它会忽略掉节点内部包含的所有 HTML,只返回纯文字内容
html = '''
<div class="wrap">
<div id="container">
<ul class="list">
<li class="item-0">first item</li>
<li class="item-1"><a href="link2.html">second item</a></li>
<li class="item-0 active"><a href="link3.html"><span class="bold">third item</span></a></li>
<li class="item-1 active"><a href="link4.html">fourth item</a></li>
<li class="item-0"><a href="link5.html">fifth item</a></li>
</ul>
</div>
</div>
'''
from pyquery import PyQuery as pq
doc = pq(html)
a = doc('.item-0.active a')
print(a)
print(a.text())
运行结果:
<a href="link3.html"><span class="bold">third item</span></a>
third item
获取这个节点内部的 HTML 文本,就可以用 html() 方法
from pyquery import PyQuery as pq
doc = pq(html)
a = doc('.item-0.active a')
print(a)
print(a.html())
运行结果:
<a href="link3.html"><span class="bold">third item</span></a>
<span class="bold">third item</span>
在多个节点的情况下,html() 方法返回第一个 li 节点的内部 HTML 文本,而 text() 返回所有的 li 节点内部纯文本
节点操作
PyQuery 提供了一系列方法来对节点进行动态修改操作
add_class、remove_class
添加、删除类属性
from pyquery import PyQuery as pq
doc = pq(html)
li = doc('.item-0.active')
print(li)
li.remove_class('active')
print(li)
li.add_class("active")
print(li)
返回结果:
<li class="item-0 active"><a href="link3.html"><span class="bold">third item</span></a></li>
<li class="item-0"><a href="link3.html"><span class="bold">third item</span></a></li>
<li class="item-0 active"><a href="link3.html"><span class="bold">third item</span></a></li>
attr、text、html
from pyquery import PyQuery as pq
doc = pq(html)
li = doc('.item-0.active')
print(li)
li.attr('name','link')
print(li)
li.text('chaned item')
print(li)
li.html('<span>changed item</span')
print(li)
attr() 方法如果只传入第一个参数属性名,则是获取这个属性值,如果传入第二个参数,可以用来修改属性值,text() 和 html() 方法如果不传参数是获取节点内纯文本和 HTML 文本,如果传入参数则是进行赋值
返回结果:
<li class="item-0 active"><a href="link3.html"><span class="bold">third item</span></a></li>
<li class="item-0 active" name="link"><a href="link3.html"><span class="bold">third item</span></a></li>
<li class="item-0 active" name="link">chaned item</li>
<li class="item-0 active" name="link"><span>changed item</span></li>
remove
移除
实例:
html = '''
<div class="wrap">
Hello, World
<p>This is a paragraph.</p>
</div>
'''
from pyquery import PyQuery as pq
doc = pq(html)
wrap = doc('.wrap')
print(wrap.text())
运行结果:
Hello, World
This is a paragraph.
例子:移除p节点
from pyquery import PyQuery as pq
doc = pq(html)
wrap = doc('.wrap')
wrap.find('p').remove()
print(wrap.text())
运行结果:
Hello, World
另外其实还有很多节点操作的方法,比如 append()、empty()、prepend() 等方法,这些函数和 jQuery 的用法是完全一致的。
伪类选择器
例如选择第一个节点、最后一个节点、奇偶数节点、包含某一文本的节点等等
实例:
html = '''
<div class="wrap">
<div id="container">
<ul class="list">
<li class="item-0">first item</li>
<li class="item-1"><a href="link2.html">second item</a></li>
<li class="item-0 active"><a href="link3.html"><span class="bold">third item</span></a></li>
<li class="item-1 active"><a href="link4.html">fourth item</a></li>
<li class="item-0"><a href="link5.html">fifth item</a></li>
</ul>
</div>
</div>
'''
from pyquery import PyQuery as pq
doc = pq(html)
# 第一个 li 节点
li = doc('li:first-child')
print(li)
# 最后一个 li 节点
li = doc('li:last-child')
print(li)
# 第二个 li 节点
li = doc('li:nth-child(2)')
print(li)
# 第三个 li 之后的 li 节点
li = doc('li:gt(2)')
print(li)
# 偶数位置的 li 节点
li = doc('li:nth-child(2n)')
print(li)
# 包含 second 文本的 li 节点
li = doc('li:contains(second)')
print(li)
运行结果:
<li class="item-0">first item</li>
<li class="item-0"><a href="link5.html">fifth item</a></li>
<li class="item-1"><a href="link2.html">second item</a></li>
<li class="item-1 active"><a href="link4.html">fourth item</a></li>
<li class="item-0"><a href="link5.html">fifth item</a></li>
<li class="item-1"><a href="link2.html">second item</a></li>
<li class="item-1 active"><a href="link4.html">fourth item</a></li>
<li class="item-1"><a href="link2.html">second item</a></li>
最后更新于
这有帮助吗?