Beautifulsoup库简介
在介绍使用css选择器之前,我们先来了解一下要与其配合使用的Beautifulsoup库
Beautiful Soup 是一个可以从HTML或XML文件中提取数据的Python库.它能够通过你喜欢的转换器实现惯用的文档导航,查找,修改文档的方式.Beautiful Soup会帮你节省数小时甚至数天的工作时间.
安装
Beautifulsoup库的安装和requests库的安装类似,只要在命令行中用pip命令就可以了
$ pip install beautifulsoup4
Beautifulsoup库的使用
还是以百度首页为例,我们先用requests库的get方法获得页面
import requests
# 从bs4库中导入Beautifulsoup类
from bs4 import BeautifulSoup
url = "http://www.baidu.com"
r = requests.get(url)
r.encoding = 'utf-8'
# 用一个变量来保存爬到的页面
html = r.text
# 使用‘lxml HTML’作为解释器解析HTML
soup = BeautifulSoup(html, 'lxml')
# 格式化输出
print(soup.prettify())
# result
#
#
#
#
#
#
#
# 百度一下,你就知道
#
#
#
#
#
#
# ... ...
可以看到,用Beautifulsoup库解析之后的HTML被转换成了标签树,标签树的每一个节点都是一个python对象,因此我们就可以很方便地对标签树进行操作。
CSS选择器
CSS选择器是一种单独的文档搜索语法。Beautiful Soup支持大部分的CSS选择器,Tag和Beautifulsoup对象的.select()
方法可以通过传入字符串参数找到对应的标签。
例如我们要找title标签:
title = soup.select("title")
print(title)
# [百度一下,你就知道 ]
也可以通过标签逐层查找:
title = soup.select('html head title')
print(title)
# [百度一下,你就知道 ]
直接子标签查找:
a = soup.select('p > a')
print(a)
'''
[关于百度,
About Baidu,
使用百度前必读,
意见反馈]
'''
通过类名和id查找:
# 查找class='lb'的标签
print(soup.select('.lb'))
# 查找id='cp'的标签
print(soup.select('#cp'))
'''
[登录]
[]
'''
除了以上的一些基本的查找方法外,还有组合查找、属性查找、语言设置查找等,可以参看官方文档中关于选择器的一节
正则表达式
正则表达式(Regular Expression)是一种文本模式,包括普通字符(例如,a 到 z 之间的字母)和特殊字符(称为"元字符")。
正则表达式使用单个字符串来描述、匹配一系列匹配某个句法规则的字符串。
简单来说,正则表达式是用来简洁表达一组字符串的表达式。
举个简单的例子,比如你要匹配字符串中的'PY''PYY''PYYYY'......'PYYYYYYYY...',它们对应的正则表达式就是'PY+'
总的来说,正则表达式是
- 通用的字符串表达框架
- 简洁表达一组字符串的表达式
- 针对字符串表达’简洁‘和’特征’思想的工具
- 判断某字符串的特征归属
正则表达式描述了一种字符串匹配的模式(pattern),可以用来检查一个串是否含有某种子串、将匹配的子串替换或者从某个串中取出符合某个条件的子串等。
正则表达式由字符和操作符构成
常用的操作符
操作符
说明
.
表示任何单个字符
[]
字符集,对单个字符给出取值范围
[^]
非字符集,对单个字符给出排除范围
*
前一个字符的0次或无限次扩展
+
前一个字符的1次或无限次扩展
?
前一个字符的0次或1次扩展
|
左右表达式的任意一个
{m}
扩展前一个字符m次
{m,n}
扩展前一个字符m次到n次(包含)
^
匹配字符串开始
$
匹配字符串结尾
()
分组标记,内部只能使用|
\d
数字,等价于[0-9]
\w
单词字符,等价于[A-Zz-z0-9_]
一些实例
正则表达式
对应字符串
P(Y|YT|YTH|YTHO)?N
'PN', 'PYN', 'PYTN', 'PYTHN', 'PYTHON'
PYTHON+
'PYTHON', 'PYTHONN',......,'PYTHONNN......'
PYTH[ON]
'PYTHO', 'PYTHN'
PYTH{1,3}ON
'PYTHON', 'PYTHHON', 'PYTHHHON'
^[A-Za-z]+$
匹配由26个字母组成的字符串
^-?\d+$
匹配整数字符串
[1-9]\d{5}
中国境内邮政编码
[\u4e00-\u9fa5]
匹配中文字符
Re库
re库是python中用于正则表达式匹配操作的标准库,不需要安装,可以直接通过import re
导入
re库采用的是原生字符串类型来表示正则表达式,原生字符串特点就是字符串中的‘\’不被解释为转义符,表示原生字符串只需要在字符串前面加上r就可以了
re库的主要功能函数:
函数
说明
re.search()
在一个字符串中搜索匹配正则表达式的第一个位置,返回match对象
re.match()
从一个字符串的开始位置起匹配正则表达式,返回match对象
re.findall()
搜索字符串,以列表类型返回全部能匹配的子串
re.split()
将一个字符串按照正则表达式匹配结果进行分割,返回列表类型
re.finditer()
搜索字符串,返回一个匹配结果的迭代类型,每个迭代元素是match对象
re.sub()
在一个字符串中替换所有匹配正则表达式的子串,返回替换后的字符串
re.match(pattern, string, flags=0)
∙ pattern : 正则表达式的字符串或原生字符串表示
∙ string : 待匹配字符串
∙ flags : 正则表达式使用时的控制标记
match()和search()的区别在于,match方法是从字符串的起始位置开始匹配,如果有一个字符不同便结束匹配,返回None
;而search方法则是搜索整个字符串匹配符合规则的子串,以下是两种方法的比较
import re
re.search(r'b', 'abcba') # <_sre.SRE_Match object; span=(1, 2), match='b'>
re.match(r'b', 'abcba') # no match
re.search(r'a', 'abcba') # <_sre.SRE_Match object; span=(0, 1), match='a'>
re.match(r'a', 'abcba') # <_sre.SRE_Match object; span=(0, 1), match='a'>
如果匹配成功,返回的是一个match对象,其中包含很多信息
match对象的属性和方法
属性
说明
方法
说明
.string
待匹配的文本
.group(0)
获得匹配后的字符串
.re
匹配时使用的patter对象(正则表达式)
.start()
匹配字符串在原始字符串的开始位置
.pos
正则表达式搜索文本的开始位置
.end()
匹配字符串在原始字符串的结束位置
.endpos
正则表达式搜索文本的结束位置
.span()
返回(.start(), .end())
re.findall(pattern, string, flags=0)
findall方法返回的是所有符合匹配规则的字符串组成的列表,顺序是根据字符串从左到右
re.split(pattern, string, maxsplit=0, flags=0)
根据pattern的出现拆分字符串。如果在pattern中使用捕获括号,则模式中所有组的文本也会作为结果列表的一部分返回。maxsplit表示最大分割数,如果maxsplit不为零,则至多出现maxsplit分裂,并且字符串的其余部分作为列表的最后一个元素返回。
import re
re.split(r'b', 'abcba') # ['a', 'c', 'a']
re.split(r'(b)', 'abcba') # ['a', 'b', 'c', 'b', 'a']
re.split(r'b', 'abcba', 1) # ['a', 'cba']
re.split(r'(b)', 'abcba', 1) # ['a', 'b', 'cba']
re.finditer(pattern, string, flags=0)
与findall方法作用相同,只不过是以迭代器的形式返回
re.sub(pattern, repl, string, count=0, flags=0)
· repl:替换匹配字符串的字符串
∙ count : 匹配的最大替换次数,为0时替换全部
将string中最左侧非重叠出现的pattern替换为repl,返回所获得的字符串。如果未找到该模式,则字符串将保持不变。repl 可以是一个字符串或一个函数
import re
re.sub(r'b','d','abcba') # 'adcda'
re.sub(r'b','d','abcba', 1) # 'adcba'
flags
可以看到之前所以的函数中都有一个参数flags
,它是用来配置正则表达式的匹配模式的。
取值可以使用按位或运算符|
表示同时生效,比如re.I | re.M
。(来自静觅)
-
re.I
(全拼:IGNORECASE): 忽略大小写(括号内是完整写法,下同)
-
re.M
(全拼:MULTILINE): 多行模式,改变’^’和’$’的行为
-
re.S
(全拼:DOTALL): 点任意匹配模式,改变’.’的行为
-
re.L
(全拼:LOCALE): 使预定字符类 \w \W \b \B \s \S 取决于当前区域设定
-
re.U
(全拼:UNICODE): 使预定字符类 \w \W \b \B \s \S \d \D 取决于unicode定义的字符属性
-
re.X
(全拼:VERBOSE): 详细模式。这个模式下正则表达式可以是多行,忽略空白字符,并可以加入注释。
Chrome开发者工具
如何调出Chrome开发者工具
- 按F12打开
- 单击右键,在菜单中点击“检查”打开
常用面板模块
- 元素(Elements)
- 网络(Network)
这里只介绍在写爬虫时可能会用到的两个功能模块,如果想了解其他的可以在网上找详细的教程
元素(Element)
单击Element标签页,页面左边显示的是HTML的结构,右边是选中元素的全部属性
- 鼠标移到某个元素上,页面视图上对应的地方会变成蓝色背景,可以用于定位元素对应的源代码。
- 选中一个元素,在底部可以看到该元素在HTML结构中的位置关系
- 右键一个元素可以对其进行修改,菜单从上到下依次是
- Add attribute : 为该元素添加属性
- Edit attribute:修改该元素的属性
- Delete element:删除元素
- Copy:复制元素的一些信息,移到上面会显示二级菜单
- ... ...
- 写某个元素的CSS选择器的时候,可以右键该元素,copy selector(有些版本叫CSS path或者CSS selector)
右侧显示的是选中元素的CSS属性,在Styles可以对CSS属性进行修改,删除和添加,仅对当前显示的页面生效,不会影响到源代码。
网络(Network)
Network是一个监控当前网页所有的http请求的面版,它主体部分展示的是每个http请求,每个字段表示着该请求的不同属性和状态
- name:请求的文件名称
- status:状态代码
- type:文件类型
- initiator:请求源
- time:请求的时间
- waterfall:请求发送过程的状态轴
当你按F5刷新页面的时候,可以看到最中间的的时间轴上花花绿绿的一条条线显示出来。这个记录的是页面在加载过程中所有的请求发出的时间和过程,你可以用鼠标选择一段时间,来观察这一段时间发出的请求内容
单击Name一列任意一个请求的文件名,则会跳出这个请求对应的参数header(表头信息、返回信息、请求基本状态等),Preview(返回的格式化转移后文本信息)、response(转移之前的原始信息)、Cookies(该请求带的cookies)、Timing(请求时间变化)。这些东西可以用来分析请求,在讲反爬虫的时候我们会深入介绍。
参考资料:
Beautifulsoup库官方文档
re库官方文档