python BeautifulSoup 获取 a_解析数据


上节课讲了爬虫的四个步骤分别为获取数据、解析数据、提取数据和存储数据,同时还讲到获取数据需要用到requests库。本节课要讲的是解析数据和提取数据需要用到的BeautifulSoup库。

之所以需要解析数据是因为我们获取到的数据是以HTML源代码的形式返回的,需要使用能读懂html的工具,才能得到想要的数据。而提取数据是从服务器返回的众多数据中,找到想要的数据。

由于BeautifulSoup库是第三方库,因此需要单独安装,Windows系统的安装方法是在命令提示符(cmd)中输入pip install BeautifulSoup4,Mac的是输入pip3 install BeautifulSoup4。安装完成后让我们来看看BeautifulSoup是如何解析数据的。

通过如下代码我们可以得到一个res对象,并确认数据返回成功。注:括号内的URL可换成想要爬取数据的网页的地址。


import requests
res = requests.get('URL')
print(res.status_code)


在此基础上,引入BeautifulSoup解析数据,留意第2行和第5行代码。如下所示:


import requests
from bs4 import BeautifulSoup
res = requests.get('URL')
print(res.status_code)
soup = BeautifulSoup(res.text,'html.parser')


第2行是引入BeautifulSoup库。第5行有两个参数,第0个是要被解析的文本,第1个是解析器。顺便多说一句,html.parser不是python中唯一的解析器。

以上是BeautifulSoup的用法,由此我们可以看出其变现形式为:bs对象 = BeautifulSoup(要解析的文本,'解析器')。

到这里就完成了解析数据,接下来要做的是提取数据。提取数据仍然用BeautifulSoup来进行,需要用到其中的两个方法find()和find_all()。

find()和find_all()的用法一样,都是根据html的标签和属性,把BeautifulSoup对象中符合要求的数据提取出来,区别在于它们的工作量。

find()只提取首个满足要求的数据,不管后面是否还有满足的,立即停止寻找并返回。find_all()则会提取出所有满足要求的数据,一起打包返回。

两者的写法基本相同,分别为:BeautifulSoup对象.find(标签,属性)和BeautifulSoup对象.find_all(标签,属性)。其中标签指的是html中<div>、<body>、<html>等元素,属性指的是class属性、id属性、style属性等。

下面通过一个实例来看看两者的区别。下图是一个简易的网页,网页主体<body></body>里面有三个div元素,先用find()提取其中的第一个元素。代码如下:


python BeautifulSoup 获取 a_python class用法_02


import requests
from bs4 import BeautifulSoup
res = requests.get(‘URL’)
soup = BeautifulSoup(res.text,'html.parser') 
item = soup.find('div')
print(item)


运行上面的代码,打印出的结果是<div>大家好,下面进入python学习</div>。要提取所有的div元素,需要将代码中的find()改为find_all(),代码如下:


import requests
from bs4 import BeautifulSoup
res = requests.get('URL')
soup = BeautifulSoup(res.text,'html.parser') 
item = soup.find_all('div')
print(item)


运行上面代码,打印出的结果是[<div>大家好,下面进入python学习</div>,<div>学习python最重要的是</div>,<div>亲手写代码</div>]。从结果上我们可以看出提取多个元素时,是以列表的形式存储的。

但列表并非是我们想要的,我们想要的是列表中的值,因此需要通过for循环遍历列表,把三个div元素提取出来。代码如下:


import requests
from bs4 import BeautifulSoup
res = requests.get('URL')
soup = BeautifulSoup(res.text,'html.parser') 
item = soup.find_all('div')
for i in item:
    print(i)


前面说到find()和find_all()的括号中有标签和属性两个参数,上面的案例都是通过标签进行提取,那么什么时候会用到属性这个参数呢?

还是上面图中的案例,我们发现“亲手写代码”这几个字不论是字体还是颜色都与其他字不同,这是因为这个<div>标签中有属性class='style_1'。通过属性可以改变字体和图片的大小、颜色、间距、对齐方式等。这里只改变了字体的大小和颜色。

因此,我们要想只提取“亲手写代码”这行,就需要通过标签和属性两个参数来定位。代码如下:


import requests
from bs4 import BeautifulSoup
res = requests.get(‘URL’)
soup = BeautifulSoup(res.text,'html.parser') 
item = soup.find('div',class_='style_1')
print(item)


运行上面的代码,打印的结果是<div class_="style_1">亲手写代码</div>。这里需要注意,为了和python语法中的类class区分,避免程序冲突,需要在class后面加下划线_,写成class_。

到了这一步,打印出的并非我们想要的目标数据,因为里面包含着html标签。至于如何提取其中的目标数据,这里先卖个关子,下节课再讲。

另外,虽然爬虫涉及到部分html知识点,但内容很简单,因此没有在文章中讲述,不了解html的读者可以自行查询学习。不用担心学不会,html在编程中算是非常简单易学的。