目录
一、解析网页数据的技术
1.正则表达式
2.XPath
3.Beautiful Soup
4.JSONPath
二、正则表达式的语法
1.元字符
2.预定义字符集
三、 re 模块的使用
1.创建 Pattern 对象
2.全文匹配
一、解析网页数据的技术
当服务器成项响应请求返回网页的数据后,我们需要从纷杂的网页数据中提取与目标相
关的数据,这个过程可以理解为解析网页数据。解析网页数据是网络爬虫工作中的关键步骤,
这一步骤主要做的事情是结合网页数据的格式特点,选择合适的技术对整个网页的数据进行
解析,并从中提取出我们最终需要的数据。
Python 中提供了正则表达式、
Xpath
、
Beautiful Soup
、
JSONPath
等多种解析网页数据的
技术,关于这些技术的介绍如下。
1.正则表达式
正则表达式是一种文本模式,这种模式描述了匹配字符串的规则,用于检索字符串中是
否有符合该模式的子串,或者对匹配到的子串进行替换。
正则表达式的优点是功能强大、应用广泛;缺点是只适合匹配文本的字面意义,而不适
合匹配文本意义。例如,正则表达式在匹配嵌套了
HTML
代码的文本时,会忽略
HTML
代码
本身存在的层次结构,而将
HTML
代码内容作为普通文本进行搜索。
2.XPath
XPath 是
XML
路径语言,用于从
HTML
或
XML
格式的数据中提取所需的数据。
XPath
适合用于处理层次结构比较明显的数据,它能够基于
HTML
或
XML
的节点树确定目标节点
所在的路径,顺着这个路径便可以找到文本节点或属性节点。
3.Beautiful Soup
Beautiful Soup 是一个可以从
HTML
或
XML
文件中提取数据的
Python
库。它同样可以使
用
XPath
语法提取数据,并且也在此基础上做了方便开发者使用的封装,提供了更多选取节
点的方式。
4.JSONPath
JSONPath 的用法类似于
XPath
,也是通过表达式的方式解析数据的,但只能解析
JSON
格式的数据。
综上所述,若要解析纯文本格式的数据,则可以选择正则表达式;若要解析 HTML
或
XML
格式的数据,则可以选择正则表达式、
XPath
、
Beautiful Soup
;若要解析
JSON
格式的数据,
则可以选择
JSONPath
。
为方便开发者使用这些技术,Python
提供了一些库或模块进行支持,包括
re
、
lxml
、
bs4
、
jsonpath
。其中,
re
模块支持正则表达式;
lxml
库和
bs4
库支持
XPath
;
jsonpath
模块支持
JSONPath
。
bs4
库是
Beautiful Soup
的最新版本,它的全称为
Beautiful Soup 4
。关于这些库或
模块的用法,我们会在后面进行详细介绍。
正则表达式与 re 模块
二、正则表达式的语法
正则表达式是对字符串操作的一种逻辑公式,它会将事先定义好的一些特定字符及它们的组
合组成一个规则字符串,并且通过这个规则字符串表达对给定字符串的过滤逻辑。
正则表达式的过滤逻辑类似于模糊匹配。例如,字符串的内容为“我爱学习,我爱工作”
时,如果要提取“学习”“工作”,通过正则表达式匹配“我爱”后面的内容就可以找到了。
一条正则表达式也称为一个模式,使用某个模式可以匹配指定文本中与表达式模式相同
的字符串。正则表达式由普通字符、元字符或预定义字符集组成。其中,普通字符包括字母、
数字、符号等,下面分别对元字符和预定义字符集进行介绍。
1.元字符
在正则表达式中,元字符是指具有特殊含义的专用字符,主要用于规定其前导字符在给
定字符串中出现的模式。常用的元字符如表
4-1
所示。
下面通过列举一些示例来说明表
4-1
中元字符的用法。
- J.m:匹配以“J”开始、以“m”结尾的字符串,匹配结果可以为 J#m、Jim、J2m 等。
- ^py:匹配以“py”开始的字符串,匹配结果可以为 python、pyinstaller 等。
- on$:匹配以“on”结尾的字符串,匹配结果可以为 python、moon 等。
- a|b|c|d:匹配字符串中的“a”“b”“c”或“d”。
- [cC]hina:匹配以“c”或“C”开头、以“hina”结尾的字符串,匹配结果可以为 china
- 或 China。
- [A-Z]hina:匹配 A~Z 的任意一位大写字母,匹配结果可以为 China。
- June?:匹配元字符“?”前的字符“e”0 次或 1 次,匹配结果可以为 june 或 july。
- ht*p:匹配字符“t”0 次或多次,匹配结果可以为 hp、htp、http、htttp 等。
- ht+p:匹配字符“t”1 次或多次,匹配结果可以为 htp、http、htttp。
- ht{2}p:匹配字符“t”2 次,匹配结果可以为 http。
- ht{2,4}p:匹配字符“t”2~4 次,匹配结果可以为 http、htttp 与 httttp。
- Feb(ruary)?:匹配子组“ruary”0 次或 1 次,匹配结果可以为 Feb 或 February。
2.预定义字符集
在正则表达式中,除了前面介绍的元字符之外,还预定义了一些字符集。这些字符集以更加
简洁的方式描述了一些由普通字符和元字符组合的模式。常用的预定义字符集如表
4-2
所示。
例如,使用“\d
”匹配字符串
Regex123
中的任意一个数字,匹配结果为
1
、
2
、
3
。
三、 re 模块的使用
Python 中提供了
re
模块操作正则表达式,该模块提供了丰富的函数或方法来实现文本匹
配查找、文本替换、文本分割等功能。
re
模块的使用一般可以分为创建
Pattern
对象和全文匹
配两步操作,关于这两步操作的介绍如下。
1.创建 Pattern 对象
为了节省每次编译正则表达式的开销,保证正则表达式可以重复使用,我们可以使用
compile()
函数对正则表达式进行预编译,从而生成一个代表正则表达式的
Pattern
对象。
complie()
函数的声明如下:
compile(pattern, flags=0)
上述函数中,参数 pattern
表示一个正则表达式;参数
flags
用于指定正则表达式匹配的模
式。参数
flags
的常用取值及其含义如下。
- re.I:忽略大小写。
- re.L:做本地化识别(locale-aware)匹配,使预定义字符集\w、\W、\b、\B、\s、\S
- 取决于当前区域设定。
- re.M:多行匹配,影响“^”和“$”。
- re.S:使字符“.”匹配所有字符,包括换行符。
- re.U:根据 Unicode 字符集匹配字符。
- re.A:根据 ASCII 字符集匹配字符。
- re.X:允许使用更灵活的格式(多行、忽略空白字符、加入注释)书写正则表达式。
- 例如,编写一个用于匹配汉字的正则表达式“[\u4e00-\u9fa5]+”,使用 compile()函数创建
- 可匹配汉字的 Pattern 对象 regex_obj,具体代码如下。
import re
# 创建 Pattern 对象
regex_obj = re.compile(r'[\u4e00-\u9fa5]+')
print(type(regex_obj))
运行代码,输出如下结果。
<class 're.Pattern'>
2.全文匹配
如果希望从全部文本中匹配所有符合正则表达式的字符串,则可以使用 Pattern
对象的
findall()
函数与
finditer()
函数。其中,
findall()
函数用于获取目标文本中所有与正则表达式匹配
的内容,并将所有匹配的内容以列表的形式返回;
finditer()
函数同样可以用于获取目标文本中
所有与正则表达式匹配的内容,但会将匹配到的子串以迭代器的形式返回。以
findall()
函数为
例介绍全文匹配,
findall()
函数的声明如下。
findall(pattern, string, flags=0)
上述函数中,参数 pattern
表示一个正则表达式;参数
string
表示待匹配的文本;参数
flags
用于指定正则表达式匹配的模式,该参数的取值与
compile()
函数中
flags
参数的取值相同。
下面以字符串“狗的英文:dog
。猫的英文:
cat
。”为例,使用
findall()
方法匹配该字符串
中所有的汉字,示例代码如下。
import re
string = "狗的英文:dog。猫的英文:cat。"
reg_zhn = re.compile(r"[\u4e00-\u9fa5]+")
print(re.findall(reg_zhn, string))
在上述代码中,我们首先定义了一个字符串 string
,然后使用
compile()
函数创建了一个
Pattern
对象,用于匹配字符串中的中文字符,最后通过
findall()
函数查找所有符合匹配规则的
子串,并使用
print()
函数输出。
运行代码,输出如下结果。
['狗的英文', '猫的英文']