bs4库的使用 正则表达式

Beautiful Soup(简称bs4)是一个用于从HTML和XML文件中提取数据的Python库。它创建一个解析树,用于处理以HTML或XML标记为单位的文档。以下是Beautiful Soup的全面使用和语法介绍:

安装

pip install beautifulsoup4
pip install lxml  # 推荐的解析器之一
pip install html5lib  # 另一种解析器

基本用法

from bs4 import BeautifulSoup

# 示例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" 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>
"""

# 创建BeautifulSoup对象
soup = BeautifulSoup(html_doc, 'html.parser')

# 格式化输出
print(soup.prettify())

解析器选项

  • html.parser: Python内置的HTML解析器
  • lxml: 快速而高效的解析器,需要安装lxml库
  • html5lib: 最为严格的解析器,能够解析更宽松的HTML代码
soup = BeautifulSoup(html_doc, 'lxml')
# 或
soup = BeautifulSoup(html_doc, 'html5lib')

对象的种类

Beautiful Soup将文档转换为4种Python对象:

  1. Tag
  2. NavigableString
  3. BeautifulSoup
  4. Comment
Tag
print(soup.title)
print(soup.head)
print(soup.a)
print(soup.p)

# 获取Tag的属性
print(soup.a['href'])
print(soup.a['class'])

# 修改属性
soup.a['class'] = 'newClass'
del soup.a['href']
NavigableString
print(soup.title.string)
BeautifulSoup对象
print(type(soup))
print(soup.name)
print(soup.attrs)
Comment
markup = "<p><!--This is a comment--></p>"
soup = BeautifulSoup(markup, 'html.parser')
comment = soup.p.string
print(type(comment))
print(comment)

遍历文档树

子节点
print(soup.head.contents)
print(soup.body.contents)
后代节点
for child in soup.descendants:
    print(child)
父节点
print(soup.title.parent)
兄弟节点
print(soup.a.next_sibling)
print(soup.a.previous_sibling)
遍历所有兄弟节点
for sibling in soup.a.next_siblings:
    print(sibling)

搜索文档树

find_all方法
# 查找所有<a>标签
print(soup.find_all('a'))

# 通过class查找
print(soup.find_all(class_='sister'))

# 通过属性查找
print(soup.find_all(id='link2'))

# 通过正则表达式查找
import re
print(soup.find_all(href=re.compile("elsie")))

# 限制返回结果数量
print(soup.find_all('a', limit=2))
find方法
# 查找第一个<a>标签
print(soup.find('a'))
select方法 (CSS选择器)
# 通过标签名
print(soup.select('title'))

# 通过类名
print(soup.select('.sister'))

# 通过id
print(soup.select('#link1'))

# 组合选择器
print(soup.select('p .sister'))

# 属性选择器
print(soup.select('a[href="http://example.com/elsie"]'))

修改文档树

修改节点内容
tag = soup.a
tag.string = "New Link Text"
print(tag)
插入新节点
new_tag = soup.new_tag("a", href="http://example.com")
new_tag.string = "New Link"
soup.p.append(new_tag)
print(soup.p)
删除节点
soup.a.decompose()
print(soup.p)

提取信息

# 获取标签的名字
print(soup.a.name)

# 获取标签的属性
print(soup.a['href'])

# 获取标签的文字内容
print(soup.a.string)

常见应用场景

从网页获取数据
import requests

url = 'http://example.com'
response = requests.get(url)
soup = BeautifulSoup(response.content, 'html.parser')

# 提取所需信息
for link in soup.find_all('a'):
    print(link.get('href'))

以上介绍了Beautiful Soup的基本用法和语法,可以帮助你从HTML和XML文档中提取和处理数据。根据具体需求,可以灵活使用这些方法来解析和操作文档。

find_allselect是Beautiful Soup中用来查找文档元素的两种常用方法,但它们有一些显著的区别:

find_all方法

  • 用法: 通过标签名、属性、文本内容等查找元素。
  • 语法: soup.find_all(name, attrs, recursive, string, limit, **kwargs)
  • 参数:
    • name: 标签名,字符串或正则表达式。
    • attrs: 属性值,字典形式。
    • recursive: 布尔值,是否递归查找子标签。
    • string: 文本内容,字符串或正则表达式。
    • limit: 限制返回的结果数量。
    • **kwargs: 其他属性,可以直接作为关键字参数传入。
示例
# 通过标签名查找
soup.find_all('a')

# 通过类名查找
soup.find_all(class_='sister')

# 通过属性查找
soup.find_all(id='link2')

# 通过正则表达式查找
import re
soup.find_all(href=re.compile("elsie"))

# 限制返回结果数量
soup.find_all('a', limit=2)

select方法

  • 用法: 通过CSS选择器查找元素。
  • 语法: soup.select(selector, limit=None)
  • 参数:
    • selector: CSS选择器,字符串形式。
    • limit: 限制返回的结果数量。
示例
# 通过标签名查找
soup.select('a')

# 通过类名查找
soup.select('.sister')

# 通过id查找
soup.select('#link2')

# 组合选择器
soup.select('p .sister')

# 属性选择器
soup.select('a[href="http://example.com/elsie"]')

区别

  1. 查找方式:

    • find_all通过标签名、属性、文本等查找,参数为关键字或字典形式。
    • select通过CSS选择器查找,参数为CSS选择器字符串。
  2. 灵活性:

    • find_all可以使用正则表达式,更加灵活。
    • select使用CSS选择器,更加直观和简洁。
  3. 易用性:

    • 如果熟悉CSS选择器,select更易用,因为它直接使用CSS选择器语法。
    • find_all可能需要更多的参数设置,尤其是在查找复杂条件时。
  4. 性能:

    • 对于简单查找,性能差异不大。
    • 对于复杂查找,find_all可能更高效,尤其是需要使用正则表达式的场景。

总结

  • 使用find_all时,适合需要灵活运用标签名、属性、正则表达式等进行复杂查找的情况。
  • 使用select时,适合熟悉CSS选择器并且需要简洁代码的情况。

具体使用哪种方法,取决于你的查找需求和对CSS选择器的熟悉程度。

正则表达式(Regular Expression,简称regex或regexp)是一种用来匹配字符串中字符组合的模式。正则表达式通常被用来检索、替换、匹配文本。它们在文本处理和数据验证中非常强大和灵活。正则表达式的完整语法非常丰富,包含了多种元字符、字符类、量词、边界匹配、分组和反向引用等。以下是正则表达式的详细语法介绍:

字符匹配

  • 普通字符:直接匹配自身,例如a匹配字符’a’。
  • 转义字符:使用反斜杠\转义特殊字符,例如\.匹配字符’.'。

元字符

  • .:匹配除换行符外的任意单个字符。
  • ^:匹配字符串的开头。
  • $:匹配字符串的结尾。
  • *:匹配前面的子表达式零次或多次,等价于{0,}
  • +:匹配前面的子表达式一次或多次,等价于{1,}
  • ?:匹配前面的子表达式零次或一次,等价于{0,1}
  • {n}:精确匹配n次。
  • {n,}:至少匹配n次。
  • {n,m}:匹配n到m次。

字符类

  • [abc]:匹配’a’, 'b’或’c’中的任意一个字符。
  • [a-z]:匹配任意一个小写字母。
  • [A-Z]:匹配任意一个大写字母。
  • [0-9]:匹配任意一个数字。
  • [^abc]:匹配除’a’, 'b’或’c’之外的任意一个字符。
  • [^0-9]:匹配除数字之外的任意一个字符。

特殊序列

  • \d:匹配任意一个数字,相当于[0-9]
  • \D:匹配任意一个非数字字符,相当于[^0-9]
  • \w:匹配任意一个字母、数字或下划线字符,相当于[a-zA-Z0-9_]
  • \W:匹配任意一个非字母、数字或下划线字符,相当于[^a-zA-Z0-9_]
  • \s:匹配任意一个空白字符(包括空格、制表符、换行符等)。
  • \S:匹配任意一个非空白字符。
  • \b:匹配一个单词边界。
  • \B:匹配一个非单词边界。

分组和反向引用

  • (...):分组,将括号中的子表达式作为一个整体。
  • |:逻辑或,匹配|前或|后的表达式。
  • \number:引用分组,第number个分组匹配的内容。

零宽断言

  • (?=...):正向肯定预查,要求接下来的字符匹配...
  • (?!...):正向否定预查,要求接下来的字符不匹配...
  • (?<=...):反向肯定预查,要求前面的字符匹配...
  • (?<!...):反向否定预查,要求前面的字符不匹配...

常用模式

  • \A:匹配字符串的开头。
  • \Z:匹配字符串的结尾,只匹配结尾的字符。
  • \z:匹配字符串的结尾。
  • \G:匹配最后匹配结束的位置。

示例

以下是一些常见的正则表达式示例:

import re

# 匹配一个邮箱地址
pattern = r'[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+'
text = "Please contact us at support@example.com"
match = re.search(pattern, text)
if match:
    print(match.group())  # 输出: support@example.com

# 验证电话号码 (格式: 123-456-7890)
pattern = r'\d{3}-\d{3}-\d{4}'
text = "My phone number is 123-456-7890."
match = re.search(pattern, text)
if match:
    print(match.group())  # 输出: 123-456-7890

# 查找所有的数字
pattern = r'\d+'
text = "There are 12 apples, 20 oranges, and 33 bananas."
matches = re.findall(pattern, text)
print(matches)  # 输出: ['12', '20', '33']

# 替换文本
pattern = r'apples'
replacement = 'pears'
text = "I like apples"
new_text = re.sub(pattern, replacement, text)
print(new_text)  # 输出: I like pears

# 使用分组和反向引用
pattern = r'(\d{3})-(\d{3})-(\d{4})'
text = "My phone number is 123-456-7890."
match = re.search(pattern, text)
if match:
    print(match.group(1))  # 输出: 123
    print(match.group(2))  # 输出: 456
    print(match.group(3))  # 输出: 7890

主要应用

  1. 文本搜索: 查找特定模式的文本。
  2. 文本替换: 替换文本中符合特定模式的部分。
  3. 数据验证: 验证输入数据是否符合特定格式(如邮箱、电话号码)。
  4. 文本分割: 根据特定模式拆分字符串。
  • 25
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值