BeautifulSoup

你知道吗?其实HTML就是一棵树……

创建BeautifulSoup对象

导入BeautifulSoup类

1
from bs4 import BeautifulSoup

初始化BeautifulSoup对象:传入一个html纯文本,可以open一个本地文件或者requests获取一个在线html文本。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import requests
html = requests.get(<URL>, headers = <HEADERS>, cookies = <COOKIES>).text
bsobj = BeautifulSoup(html, 'lxml')

## 一个例子
def get_html(encoding = 'gbk'):
headers = [
'Mozilla/5.0 (Windows NT 10.0; WOW64)',
'AppleWebKit/537.36 (KHTML, like Gecko)',
'Chrome/70.0.3538.67',
'Safari/537.36'
]
headers = {'User-Agent': ' '.join(headers)}
def open_url(url):
html = requests.get(url = url, headers = headers)
html.encoding = encoding
html = html.text
return(html)
return(open_url)

格式化打印BeautifulSoup对象内容:

1
print(bsobj.prettify())

bs4包的四种基本类型

  • element.Tag:HTML标签,具有name属性(标签名)和attrs属性 (标签的属性字典)
  • element.NavigableString:标签包含的文本
  • BeautifulSoup:初始化的对象,name属性值为[document],它只有一个子标签.html;
  • element.Comment:注释内容

遍历文档树

点号遍历

  • TAG.contents:list对象,直接子标签

  • TAG.children:iterator对象,直接子标签

  • TAG.descendants:iterator对象,所有子孙标签

  • TAG.string:标签内只有一个字符串,获取它

  • TAG.strings:标签内不止一个字符串,获取它们

  • TAG.striped_strings:标签内不止一个字符串,获取它们并去掉空白符

  • TAG.parent:当前标签的直接父标签,很明显只会有一个

  • TAG.parents:iterator对象,当前标签的所有祖先标签,很明显可能不止一个

下面的四个感觉用途不大,因为不够精准:

  • TAG.previous_siblingTAG.next_sibling:并列的上一个/下一个兄弟节点

  • TAG.previous_siblingsTAG.next_siblings

  • TAG.previous_elementTAG.next_element:前后节点

  • TAG.previous_elementsTAG.next_elements

find/select查找

$\blacksquare$ 表示该方法很常用,$\square$ 表示该方式不是很常用

$\blacksquare$.find_all

在所有子孙节点中搜索特定标签,返回一个list对象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
TAG.find_all(name, attrs, recursive, text, **kwargs)
# name 限制标签名,形式丰富多样:
# |- 1. 特定名称,如 name = 'title'
# |- 2. 正则表达式,如 name = re.compile(r'^b')
# |- 3. 标签列表,如 name = ['a', 'img', 'p']
# |- 4. name = True 会返回所有子孙节点
# |- 5. 一个特殊的函数:接受一个TAG,返回布尔值表示这个TAG是否被选择,例如
# def has_class_but_no_id(tag):
# return tag.has_attr('class') and not tag.has_attr('id')
# attr 一个字典,根据属性进行过滤,例如
# attr = {'class': '...', 'id': '...'}
# recursive 布尔值,True搜索子孙标签,False只搜索直接子标签
# text 匹配标签内的字符串,包含了NavigableString和Comment
# |- 与name类似,可以传入正则表达式、字符串列表、特殊函数
# kwargs 不建议使用
# limit 限制返回结果的数量,当文档树过大时有用

$\blacksquare$.find

1
2
# 只返回搜索到第一个结果
TAG.find(name, attrs, recursive, text, **kwargs)

$\square$.find_xxx

  • 父标签/祖先标签查找:.find_parent / .find_parents
  • 上一个/下一个兄弟标签:.find_previous_sibling / .find_next_sibling
  • 之前的/之后的所有兄弟标签:.find_previous_siblings / .find_next_siblings
  • 之前的/之后的一个标签:.find_previous / .find_next
  • 之前的/之后的所有标签:.find_all_previous / .find_all_next

$\blacksquare$.select

select方法接收一个特殊的字符串,该字符串的形式应按照CSS标签选择器的语法书写。

常见的CSS标签选择器语法有:

1
2
3
4
5
6
7
8
9
10
# 标签名、样式、id是查找标签的三个常用的属性
TAG.select('title') # 查找名为title的所有标签,返回list
TAG.select('.cls') # 查找样式中包含cls的所有标签,返回list
TAG.select('#myid') # 查找id为myid的所有标签,返回list

# 三个常用属性可以进行自由组合
TAG.select('head > title') # '>'连接的标签从属关系
TAG.select('table .cls #myid') # 并列查找,同时满足
TAG.select('table[class="cls",id="myid"]') #联合查找的另一种格式
TAG.select('div[class="cls"] > table[id="gold"]') # 联合查找可以和从属标签结合

其实掌握上面的几种CSS标签选择语法就足以应付大多数标签查找了,更多CSS选择器语法参考w3school教程

>>>>>>>>>>>>> 转载请注明出处 <<<<<<<<<<<<<
0%