python 第三方库BeautifulSoup4文档学习(4)

摘要:
soup=BeautifulSoupa_tags=soup.find_all("a")print#[Elsie,Lacie,Tillie]2.正则表达式需要引入re模块,导入以后可通过complie()将普通的字符串编译为正则表达式,find_all()方法将会通过正则表达式的match()去匹配soup文档中的标签。recode=re.compiletag_b_start=soup.find_allfortagintag_b_start:print#body#b3.列表如果在搜索方法中传入列表参数,那么该方法就会将列表中的任一参数符合匹配结果的返回。defhas_class_but_no_id:returntag.has_attrandnottag.has_attrtags=soup.find_allprint#[TheDormouse'sstory,Onceuponatimetherewerethreelittlesisters;andtheirnameswere#Elsie,#Lacieand#Tillie;#andtheylivedatthebottomofawell.,...]自定义的方法可以由自己的想法设计到比较复杂。namename参数可以查找所有标签符合name的值的,字符串对象会被自动过滤掉。
bs4 搜索文档树

搜索文档树有很多方法,比较常用的是find()和find_all() ,在方法中我们通常需要加上特定的参数去查找我们需要的内容,这样的参数就被看作为过滤器。

依然使用官方提供的测试html文档

html_doc = """
<html><head><title>The Dormouse's story</title></head>
<body>

<p class="title"><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"   id="link1">Elsie</a>,
<a href="http://example.com/lacie"   id="link2">Lacie</a> and
<a href="http://example.com/tillie"   id="link3">Tillie</a>;
and they lived at the bottom of a well.</p>


<p class="story">...</p>

"""

过滤器

1.字符串

通过向搜索方法中传入字符串参数进行搜索,这是最简单的一种方式,缺点在于搜索结果往往比较模糊。

soup = BeautifulSoup(html_doc,"html.parser")
a_tags = soup.find_all("a")
print(a_tags)

# [<a   href="http://example.com/elsie" id="link1">Elsie</a>, <a   href="http://example.com/lacie" id="link2">Lacie</a>, <a   href="http://example.com/tillie" id="link3">Tillie</a>]

2.正则表达式

需要引入re模块,导入以后可通过complie()将普通的字符串编译为正则表达式,find_all()方法将会通过正则表达式的match()去匹配soup文档中的标签。

recode = re.compile("^b")
tag_b_start = soup.find_all(recode)
for tag in tag_b_start:
    print(tag.name)

# body
# b

3.列表

如果在搜索方法中传入列表参数,那么该方法就会将列表中的任一参数符合匹配结果的返回。

tags_a_b = find_all(['a','b'])
for tag in tags_a_b:
    print(tag)
    
# <b>The Dormouse's story</b>
# <a   href="http://example.com/elsie" id="link1">Elsie</a>
# <a   href="http://example.com/lacie" id="link2">Lacie</a>
# <a   href="http://example.com/tillie" id="link3">Tillie</a>

这里我的列表参数只有字符串,也可以将前面的正则表达式传入列表中。

4.True

True可以匹配任何值(字符串除外)。

tags = soup.find_all(True)
for tag in tags:
    print(tag.name)
    
# html
# head
# title
# body
# p
# b
# p
# a
# a
# a
# p

自定义方法

如果在上面所列的过滤器中都无法获取想要的结果,可以自定义方法来指定自己要获取的内容。

def has_class_but_no_id(tag):
    return tag.has_attr("class") and not tag.has_attr("id")
tags = soup.find_all(has_class_but_no_id)
print(tags)

# [<p class="title"><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" id="link1">Elsie</a>,
# <a   href="http://example.com/lacie" id="link2">Lacie</a> and
# <a   href="http://example.com/tillie" id="link3">Tillie</a>;
# and they lived at the bottom of a well.</p>, <p class="story">...</p>]

自定义的方法可以由自己的想法设计到比较复杂。

find_all()方法

find_all()能够搜索并过滤当前的bs文档树中符合过滤器参数的tag的子节点;接下来着重说一下该方法中的一些参数。

name

name参数可以查找所有标签符合name的值的,字符串对象会被自动过滤掉。

a_tags = soup.find_all("a")
print(a_tags)

# [<a   href="http://example.com/elsie" id="link1">Elsie</a>, <a   href="http://example.com/lacie" id="link2">Lacie</a>, <a   href="http://example.com/tillie" id="link3">Tillie</a>]

补充:name可以为任一类型的过滤器,即可以为字符串、正则表达式、列表、True、方法。

keyword

关键字参数,顾名思义传入的是要查找的标签中的关键字,然后find_all()方法会自动查找每一哥含有关键字的标签并返回。

例如,查找包含link关键字的标签:

tags = soup.find_all(id=re.compile(r'link'))
print(tags)

# [<a   href="http://example.com/elsie" id="link1">Elsie</a>, <a   href="http://example.com/lacie" id="link2">Lacie</a>, <a   href="http://example.com/tillie" id="link3">Tillie</a>]

关键字参数部分属性无法支持,如class;但是可以find_all()attrs参数来获取

tags = soup.find_all(attrs={"class":"sister"})
print(tags)

# [<a   href="http://example.com/elsie" id="link1">Elsie</a>, <a   href="http://example.com/lacie" id="link2">Lacie</a>, <a   href="http://example.com/tillie" id="link3">Tillie</a>]

CSS搜索

我们按照CSS搜索主要是针对tag的搜索,搜索方式主要按照CSS中的class属性,但是因为class在python中是保留字,所以一般是使用class_来进行标识,下面还是一些例子来说明:

import requests
from bs4 import BeautifulSoup
import re

headers = {
    "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 Safari/537.36",
}
# 这里用百度首页为例
html = requests.get("http://www.baidu.com",headers=headers)
html.encoding = "UTF-8"
# soup文档
soup = BeautifulSoup(html.text,"html.parser")
# 查找class属性以side_entry结尾的div
div_soup_list = soup.find_all("div",class_=re.compile("aging-entry$"))
# class属性为多值属性,即一个class可能为多个值的组合,所以我们可以分别搜索tag中的每个类名
div_soup = BeautifulSoup(str(div_soup_list),"html.parser")
# tag = div_soup.find_all("div",class_="c-color-text")
tag = div_soup.find_all("div",class_="toast")
# 上面的输出结果一样都为[<div class="c-color-text toast">辅助模式</div>]
print(tag)

string参数

string参数也可以是多种类型,与name参数相似,可以是字符串、True、列表、正则表达式,使用与之前的name参数类似,具体参考例子:

a_tag = soup.find_all(string = "Lacie")
a_tag = soup.find_all(string = True)
a_tag = soup.find_all(string = ["Elsie","Lacie","Tillie"])
# string参数还能与其他参数混用,例如与name参数混用:
a_tag = soup.find_all("a",string = re.compile("^E.+?e"))

limit参数

与sql语句中的limit语句类似,当我们想要限制搜索结果时可以使用,当满足limit的限制数量时就会结束搜索并返回结果。

a_tag = soup.find_all("a",string = True,limit=2)

recursive参数

我们在使用find_all()搜索文档树时,是全文档的tag节点搜索,如果只想搜索某个节点之下的某个节点,可以使用该参数。

# 对比使用前后,使用前body是html的直接子节点,整个soup文档的孙节点,没有recursive参数限制所以能够找到;使用后只能找到html
# tag = soup.find_all("body")
tag = soup.find_all("body",recursive=False)

特别说明

简化find_all方法,我们可以像调用find_all()方法一样使用tag.例如:

#这两个例子完全等价,只要find_all()中有的,都可以直接使用tag来操作,显得更简洁
# result = soup.find_all("a")
result = soup("a")

搜索文档树使用频次最高的方法就是find_all()方法,还有其他搜索方法如find、find_parent与find_parents、find_next_sibling与find_next_siblings等,都是类似的使用,无非就是搜索的侧重点、范围不一样,这里不再一一叙述,可以查看bs4库官方文档。

通过CSS选择器搜索文档树

bs支持大部分CSS选择器,CSS语法可参考w3school,使用soup或者tag的select()方法,传入具有CSS选择器语法的字符串参数。
下面是一些例子:

# 返回的结果类型是tag.name为p的结果集
# tag_set = soup.select("p")
# tag_set = soup.select("div p")
# 返回p的子节点为a标签的元素结果集
# tag_set = soup.select("p > a")
# 返回soup文档中div中p为最后一个节点的元素结果集
# tag_set = soup.select("div p:nth-last-child(1)")

免责声明:文章转载自《python 第三方库BeautifulSoup4文档学习(4)》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇bootstrap-table 基础用法redis-共享对象池下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

Python实现快捷输入(类似WeGame的一键喊话)

故事背景:   表弟跟我说,他玩游戏玩的不是很好,导致经常被队友互动,但是自己的手速有限,经常在互动中败阵。   因此,尝试做一款小工具,帮助表弟取得和队友互动的胜利! 逻辑设计:   监听键盘上的某个按键   当该按键被按下时,调用数据库(或者远程接口)的数据   将获取到的数据写进Windows的剪贴板   模拟粘贴快捷键(Ctrl + V),将数据文...

python科学计算库-pandas

------------恢复内容开始------------ 1、基本概念 在数据分析工作中,Pandas 的使用频率是很高的,一方面是因为 Pandas 提供的基础数据结构 DataFrame 与 json 的契合度很高,转换起来就很方便。另一方面,如果我们日常的数据清理工作不是很复杂的话,你通常用几句 Pandas 代码就可以对数据进行规整。 Pand...

python处理xml大文件[xml.sax]

博客已迁移, 新地址 ===================== 之前使用过python使用dom读取简单配置xml文件的http://blog.csdn.net/wklken/article/details/7270117 今天遇到大文件处理,使用dom占用资源太多,改用sax处理 dom和sax区别可以自己google下 需求:读取xml数据文件,文...

miniconda安装和使用

一、下载和安装: 1、下载:[root@localhost ~]# wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh 2、安装: [root@localhost ~]# chmod +x Miniconda3-latest-Linux-x86_64.sh [...

Python之win32模块

如果想在Windows操作系统上使用Python去做一些自动化工作,pywin32模块常常会被用到,它方便了我们调用Windows API。 安装及使用 通过命令pip install pywin32 进行安装。安装完成后,在Lib/site-packages下,能够找到PyWin32.chm文档,通过该文档能查看每一个函数的具体用法。 实例讲解 实例1...

python 抓取cisco交换机配置文件

#!/usr/bin/python import sys import time import os import pexpect now = time.strftime('%Y-%m-%d',time.localtime(time.time()))aa = open ('/home/hanlei/test/%s/log.txt' % now, "w")...