文章目录
书接上文
Python疫情数据的爬虫和可视化显示(一)requests篇
Beautiful Soup介绍与安装
介绍
依然是去官网,看介绍
https://pypi.org/project/BeautifulSoup/
可以在描述中得知,Beautiful Soup是一个可以从HTML或XML文件中提取数据的Python库
安装
安装Beautiful Soup 4
安装指令
pip install beautifulsoup4
或者
pip install bs4
这样,就可以成功的安装好我们的Beautiful Soup 4了。但是注意描述中的说明,这个库的功能是提取数据,没有数据的处理,所以我们还需要其他的库来进行处理
安装lxml解析器
安装命令
pip install lxml
lxml在这里是一个解析器的作用,解析器其实也不止这一种
推荐使用lxml作为解析器,因为效率更高. 在Python2.7.3之前的版本和Python3中3.2.2之前的版本,必须安装lxml或html5lib, 因为那些Python版本的标准库中内置的HTML解析方法不够稳定.
Beautiful Soup对象介绍与创建
Beautiful Soup对象
Beautiful Soup对象:代表解析整个文档树
它支持 遍历文档树 和 搜索文档树 中描述的大部分的方法
创建Beautiful Soup对象
bs4.BeautifulSoup(html, 'lxml')
lxml 就是我们这次使用的解析器
代码
# 1.导入模块
from bs4 import BeautifulSoup
# 2.创建Beautifully Soup对象
soup = BeautifulSoup('<html><body><p>data</p></body></html>', 'lxml')
print(soup)
注意:
1. 这里如果忘记了自己安装模块的名字,可以使用命令pip list,就可以查找到,比如beautifulsoup4
2. 这里我用的是from bs4 import BeautifulSoup导入模块,而不是import bs4,因为我们只需要用到beautifulsoup4的BeautifulSoup函数功能,所以我们在这里使用from bs4 import BeautifulSoup只是导入了这一个函数。这样导入,就可以直接使用BeautifulSoup而不用之前的调用方式。
如果使用import bs4
,那么在使用时就要bs4.BeautifulSoup
或者beautifulsoup4BeautifulSoup
F5编译运行
Beautiful Soup对象的find方法
find方法的作用
搜索文档树
html基本结构
这里先来讲一下我们的网页背后的html语言,网页是由html语言写出来的,我们任意打开一个网页,然后点击F12,就可以看到
为了更加清晰直观的来介绍,还是用一个简单的例子
我们可以看到这样的都可以称为标签
根据位置,我们也可以更加清晰的了解到,是的父标签
像 < p class-="title "> ,意思是p标签的clss属性,它的值是title
这就是html基本的结构
使用方法
find(self, name=None, attrs={}, recursive=True, text=None, **kwargs)
参数
name:标签名
在上文中就是类似于标签
或者标签
attrs:属性字典
上面找了我们需要的标签,标签下有多的属性,那么我们就需要进一步的确定我们需要的是哪一个属性的值
recursive:是否递归循环查找
一般都会是recursive=True,可以在目录下的子目录进行查找
text:根据文本内容查找
顾名思义就是文本中的内容
返回
查找到的第一个元素对象
想要返回全部的对象,就是find_all
find_all( name , attrs , recursive , string , **kwargs )
案例:从疫情首页提取各国最新的疫情数据
思路
- 导入相关模块
- 导入请求
- 导入数据
- 发送请求,获取疫情首页的内容
- 使用Beautiful Soup提取疫情数据
现在是获得了首页的全部数据,我们需要的是各国的疫情数据,所以我们接下来要找到响应的标签,然后再使用lxml进行一个索引查找
也就是我们代码中要find的信息就应该是id=‘getListByCountryTypeService2true’
代码
# 1. 导入相关模块
import requests #导入请求
from bs4 import BeautifulSoup #导入数据
# 2. 发送请求,获取疫情首页的内容
# 2.1 发送请求,获取响应
response = requests.get('http://ncov.dxy.cn/ncovh5/view/pneumonia')
# 2.2 从响应中获取数据
home_page = response.content.decode()
# print(home_page)
# 3. 使用Beautiful Soup提取疫情数据
# 3.1 构建Beautiful Soup对象
soup = BeautifulSoup(home_page, 'lxml')
# 3.2 根据id属性查找,包含各国疫情信息的标签
script = soup.find(id='getListByCountryTypeService2true')
# 3.3 获取中文文本的内容
countrytext = script.string
print(countrytext)
home_page = response.content.decode()
这里我们可以进一步的进行体会代码的含义,打断点之后,我们可以把查看到home_page就是我们要请求得到的网页代码
soup = BeautifulSoup(home_page, 'lxml')
使用Beautiful Soup,可以看到构建出来了一个对象,并且使用lxml解析器,解析成了如下所示的信息
script = soup.find(id='getListByCountryTypeService2true')
这里我们对构建的Beautiful Soup的对象得到的信息,进行一个find,可以看到我们的代码找到了id='getListByCountryTypeService2true包含的信息
得到了信息之后,我们还要再进行处理一下,countrytext = script.string
来获取我们需要的信息,而不是一个完整的对象,可以看到,这里就只有我们需要的信息,没有了其他的内容
现在我我们可以捕捉到指定区域的内容了,那么怎么提取出来具体的内容呢?这里就需要进行一个匹配的查找
也就是接下来正则表达式的引入
正则表达式概念与作用
概念
正则表达式是一种字符串匹配的模式
作用
- 检查一个字符串是否含有某种子串
- 替换匹配的子串
- 提取某个字符串匹配的子串
正则表达式常见的语法
import re
rs = re.findall('abc', 'abcdefghijklmnopqrstuvwxyz')
print(rs)
re 是正则模块
这里的re.findall,就是在’abcdefghijklmnopqrstuvwxyz中找到’abc’,这样就可以匹配上了
更多的例子,比如rs = re.findall(‘a.c’, ‘abc’),也是可以匹配得到
如果就是要匹配a.c
,那么就要写成‘a\.c
’
对于预定义字符集的使用
特殊
rs = re.findall('a.bc', 'a\nbc', re.DOTALL)
rs = re.findall('a.bc', 'a\nbc', re.S)
如果要匹配’a\nbc’,里面有\n,直接匹配是匹配不到的,这时候需要在后面加上模式re.DOTALL或者re.S
对于’a\nbc’,如果我现在只需要a后面的,bc前面的,应该怎么操作呢?
re = re.findall('a(.+)bc', 'a\nbc', re.DOTALL)
API
- re.findall(pattern, string, flags=0)
- 作用:扫描整个string字符串,返回所有与pattern匹配的列表
- 参数:
* pattern:正则表达式
* string - 返回:返回string中与pattern中匹配的内容
特点
- 如果正则表达式中没有(),则返回与整个正则匹配的列表
- 如果正则表达式中有(),则返回()中匹配的内容列表,小括号两边东西都是负责确定提取数据所在位置
案例:提取最新的疫情数据的json字符串
思路
- 请求疫情首页的内容
- 提取script标签中各种疫情信息
- 从各国疫情信息中提取各国疫情的json字符串
代码
# 1. 导入相关模块
import requests #导入请求
import re
from bs4 import BeautifulSoup #导入数据
# 2. 发送请求,获取疫情首页的内容
# 2.1 发送请求,获取响应
response = requests.get('http://ncov.dxy.cn/ncovh5/view/pneumonia')
# 2.2 从响应中获取数据
home_page = response.content.decode()
# print(home_page)
# 3. 使用Beautiful Soup提取疫情数据
# 3.1 构建Beautiful Soup对象
soup = BeautifulSoup(home_page, 'lxml')
# 3.2 根据id属性查找,包含各国疫情信息的标签
findscript = soup.find(id = "getListByCountryTypeService2true")
# 3.3 获取中文文本的内容
countrytext = findscript.string
# print(countrytext)
# 4. 使用正则表达式提取json字符串
json_str = re.findall(r'\[.+\]', countrytext)
print(json_str)
我们接着上面的 案例:从疫情首页提取各国最新的疫情数据 开始
使用正则表达式提取json字符串
json_str = re.findall(r'\[.+\]', countrytext)
这句代码难点在于r'\[.+\]'
的含义,表示的是“[]”内的内容,因为“[]”有着其他的含义,所以还需要“/”来进行进一步说明
最后的结果如图所示的内容,匹配到了“[]”内的全部内容,也就是我们需要的各国疫情的数据
就此,我们得到了想要的json数据