LogoLogo
  • README
  • 前端编程
    • 01 Node JS
    • 02-ES6详解
    • 03-NPM详解
    • 04-Babel详解
    • 05-前端模块化开发
    • 06-WebPack详解
    • 07-Vue详解
    • 08-Git详解
    • 09-微信小程序
  • 人工智能
    • 机器学习
      • 二次分配问题
      • 非负矩阵
      • 概率潜在语义分析
      • 概率图模型
      • 集成学习
      • 降维
      • 距离度量
      • 决策树
      • 逻辑回归
      • 马尔可夫决策过程
      • 马尔可夫链蒙特卡洛法
      • 朴素贝叶斯法
      • 谱聚类
      • 奇异值分解
      • 潜在狄利克雷分配
      • 潜在语义分析
      • 强化学习
      • 社区算法
      • 时间序列模型
      • 特征工程
      • 条件随机场
      • 图论基础
      • 线性分类
      • 线性回归
      • 信息论中的熵
      • 隐马尔科夫模型
      • 支持向量机
      • 主成分分析
      • EM算法
      • Hermite 矩阵的特征值不等式
      • k-means聚类
      • k近邻法
      • PageRank算法
    • 深度学习
      • Pytorch篇
        • 01-线性模型
        • 02-梯度下降法
        • 03-反向传播
        • 04-pytorch入门
        • 05-用pytorch实现线性回归
        • 06-logistic回归
        • 07-处理多维特征的输入
        • 08-加载数据集
        • 09-多分类问题
        • 10-卷积神经网络
        • 11-循环神经网络
    • 图神经网络
      • 图神经网络笔记01
        • 01-图(Graphs)的结构
        • 02-网络的性质和随机图模型
        • 03-网络工具
        • 04-网络中的主题和结构角色
        • 05-网络中的社区结构
      • 图神经网络笔记02
        • 01-深度学习引言
        • 02-神经网络基础
        • 03-卷积神经网络
        • 04-图信号处理与图卷积神经网络
        • 05-GNN的变体与框架-
        • [06-Google PPRGo 两分钟分类千万节点的最快GNN](人工智能/图神经网络/图神经网络笔记02/06-Google%20PPRGo 两分钟分类千万节点的最快GNN.md)
        • 07-序列模型
        • 08-变分自编码器
        • 09-对抗生成网络
  • 日常记录
    • 健身日记
    • 面经记录
    • 自动生成Summary文件
  • 实战项目
    • 谷粒商城
      • 00-项目概述
      • 01-分布式基础-全栈开发篇
      • 02-分布式高级-微服务架构篇
      • 03-高可用集群-架构师提升篇
  • 数据库
    • MySQL笔记
      • 01-MySQL基础篇
      • 02-MySQL架构篇
      • 03-MySQL索引及调优篇
      • 04-MySQL事务篇
      • 05-MySQL日志与备份篇
    • Redis笔记
      • 01-Redis基础篇
      • 02-Redis高级篇
    • 02-Redis篇
  • 算法笔记
    • 01-算法基础篇
    • 02-算法刷题篇
  • 职能扩展
    • 产品运营篇
  • Go编程
    • 01-Go基础
      • 01-Go基础篇
  • Java编程
    • 01-Java基础
      • 01-Java基础篇
      • 02-多线程篇
      • 03-注射与反解篇
      • 04-JUC并发编程篇
      • 05-JUC并发编程与源码分析
      • 06-JVM原理篇
      • 07-Netty原理篇
      • 08-设计模式篇
    • 02 Java Web
      • 01-Mybatis篇
      • 01-Mybatis篇(新版)
      • 02-Spring篇
      • 02-Spring篇(新版)
      • 03-SpringMVC篇
      • 04-MybatisPlus篇
    • 03-Java微服务
      • 01-SpringBoot篇
      • 01-SpringBoot篇(新版)
      • 02-SpringSecurity篇
      • 03-Shiro篇
      • 04-Swagger篇
      • 05-Zookeeper篇
      • 06-Dubbo篇
      • 07-SpringCloud篇
      • 08-SpringAlibaba篇
      • 09-SpringCloud篇(新版)
    • 04-Java中间件
      • 数据库篇
        • 01-分库分表概述
        • 02-MyCat篇
        • 03-MyCat2篇
        • 04-Sharding-jdbc篇
        • 05-ElasticSearch篇
      • 消息中间件篇
        • 01-MQ概述
        • 02-RabbitMQ篇
        • 03-Kafka篇
        • 04-RocketMQ篇
        • 05-Pulsar篇
    • 05-扩展篇
      • Dubbo篇
      • SpringBoot篇
      • SpringCloud篇
    • 06-第三方技术
      • 01-CDN技术篇
      • 02-POI技术篇
      • 03-第三方支付技术篇
      • 04-第三方登录技术篇
      • 05-第三方短信接入篇
      • 06-视频点播技术篇
      • 07-视频直播技术篇
    • 07-云原生
      • 01-Docker篇
      • 02-Kubernetes篇
      • 03-Kubesphere篇
  • Linux运维
    • 01-Linux篇
    • 02-Nginx篇
  • Python编程
    • 01-Python基础
      • 01.配置环境
      • 02.流程控制
      • 03.数值
      • 04.操作符
      • 05.列表
      • 06.元祖
      • 07.集合
      • 08.字典
      • 09.复制
      • 10.字符串
      • 11.函数
      • 12.常见内置函数
      • 13.变量
      • 14.异常和语法错误
      • 15.时间和日期
      • 16.正则表达式
    • 02 Python Web
      • flask篇
        • 01.前言
        • 02.路由
        • 03.模板
        • 04.视图进阶
        • 05.flask-sqlalchemy
        • 06.表单WTForms
        • 07.session与cookie
        • 08.上下文
        • 09.钩子函数
        • 10.flask 信号
        • 11.RESTFUL
        • 13.flask-mail
        • 14.flask+celery
        • 15.部署
        • 16.flask-login
        • 17.flask-cache
        • 18.flask-babel
        • 19.flask-dashed
        • 20.flask-pjax
        • 21.flask上传文件到第三方
        • 22.flask-restless
        • 23.flask-redis
        • 24.flask-flash
        • 25.消息通知
        • 26.分页
    • 03-Python数据分析
      • Matplotlib
      • Numpy
      • Pandas
      • Seaborn
    • 04-Python爬虫
      • 1.准备工作
      • 2.请求模块的使用
      • 3.解析模块的使用
      • 4.数据存储
      • 5.识别验证码
      • 6.爬取APP
      • 7.爬虫框架
      • 8.分布式爬虫
由 GitBook 提供支持
在本页
  • Beautiful Soup
  • 安装
  • 用途
  • 解析器比较
  • 文档
  • 用法
  • Pyquery
  • 安装
  • 用途
  • 文档
  • 用法

这有帮助吗?

在GitHub上编辑
  1. Python编程
  2. 04-Python爬虫

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>
上一页2.请求模块的使用下一页4.数据存储

最后更新于3年前

这有帮助吗?

image-20200918105241702
img
image-20200918113118392

中文文档
官方文档
css选择器文档
参考文档