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
# <html>
# <head>
# <meta content="text/html;charset=utf-8" http-equiv="content-type"/>
# <meta content="IE=Edge" http-equiv="X-UA-Compatible"/>
# <meta content="always" name="referrer"/>
# <link href="http://s1.bdstatic.com/r/www/cache/bdorz/baidu.min.css" rel="stylesheet" type="text/css"/>
# <title>
# 百度一下,你就知道
# </title>
# </head>
# <body link="#0000cc">
# <div id="wrapper">
# <div id="head">
# <div class="head_wrapper">
# ... ...
可以看到,用Beautifulsoup库解析之后的HTML被转换成了标签树,标签树的每一个节点都是一个python对象,因此我们就可以很方便地对标签树进行操作。
CSS选择器
CSS选择器是一种单独的文档搜索语法。Beautiful Soup支持大部分的CSS选择器,Tag和Beautifulsoup对象的.select()
方法可以通过传入字符串参数找到对应的标签。
例如我们要找title标签:
title = soup.select("title")
print(title)
# [<title>百度一下,你就知道</title>]
也可以通过标签逐层查找:
title = soup.select('html head title')
print(title)
# [<title>百度一下,你就知道</title>]
直接子标签查找:
a = soup.select('p > a')
print(a)
'''
[<a href="http://home.baidu.com">关于百度</a>,
<a href="http://ir.baidu.com">About Baidu</a>,
<a href="http://www.baidu.com/duty/">使用百度前必读</a>,
<a class="cp-feedback" href="http://jianyi.baidu.com/">意见反馈</a>]
'''
通过类名和id查找:
# 查找class='lb'的标签
print(soup.select('.lb'))
# 查找id='cp'的标签
print(soup.select('#cp'))
'''
[<a class="lb" href="http://www.baidu.com/bdorz/login.gif?login&tpl=mn&u=http%3A%2F%2Fwww.baidu.com%2f%3fbdorz_come%3d1" name="tj_login">登录</a>]
[<p id="cp">©2017 Baidu <a href="http://www.baidu.com/duty/">使用百度前必读</a> <a class="cp-feedback" href="http://jianyi.baidu.com/">意见反馈</a> 京ICP证030173号 <img src="//www.baidu.com/img/gs.gif"/> </p>]
'''
除了以上的一些基本的查找方法外,还有组合查找、属性查找、语言设置查找等,可以参看官方文档中关于选择器的一节
正则表达式
正则表达式(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库官方文档
网友评论