python爬虫分析数据_Python爬虫入门 处理数据

本文介绍了如何使用Python的BeautifulSoup库解析和提取网页数据,以豆瓣读书Top250为例,详细讲解了find()和find_all()方法,以及如何通过Tag对象获取文本和属性值,最后提到了CSS选择器的使用。
摘要由CSDN通过智能技术生成

BeautifulSoup

处理数据我们需要用到一个强大的第三方库——BeautifulSoup

处理数据分为两步:解析数据 和 提取数据,解析数据指将网页源代码解析成 Python 能“读懂”的格式,而提取数据则是指将网页源代码中无关数据过滤掉,只提取出我们所需要的数据。

解析数据

我们以豆瓣读书 Top250 为例,它的网址是:sjihttps://book.douban.com/top250。

我们来看看如何将其网页源代码解析成 BeautifulSoup 对象:

import requests

from bs4 import BeautifulSoup

headers = {

'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.132 Safari/537.36'

}

res = requests.get('https://book.douban.com/top250', headers=headers)

soup = BeautifulSoup(res.text, 'html.parser')

我们通过 from bs4 import BeautifulSoup 语句导入 BeautifulSoup,然后使用 BeautifulSoup(res.text, 'html.parser') 语句将网页源代码的字符串形式解析成了 BeautifulSoup 对象。

创建 BeautifulSoup 对象时需要传入两个参数,第一个参数是要解析的 HTML 文本,即网站源代码的字符串形式(res.text)。第二个参数是解析 HTML 的解析器,html.parser 是 Python 中内置的解析器,较为简单方便。

res.text 的类型是字符串,而 soup 的类型是 BeautifulSoup 对象,它俩是完全不同的东西。相比字符串,BeautifulSoup 对象 里有很多强大的方法和属性。通过这些方法和属性,我们就能方便快捷地提取出我们所需要的数据。

提取数据

find() 方法和 find_all() 方法

find():找到符合条件的首个数据

find_all():找到符合条件的所有数据

注意对比两个输出结果的差异:

soup = BeautifulSoup(res.text, 'html.parser')

print(soup.find('a'))

# 输出:登录/注册

print(soup.find_all('a'))

# 输出:[

# 登录/注册,

# 豆瓣电影,

# 追风筝的人,

# 解忧杂货店,

# 小王子

# ]

上面代码中使用 find() 和 find_all() 方法分别提取了 a 标签 的内容。可以看到,find() 方法返回了第一个 a 标签,而 find_all() 方法则返回了所有的 a 标签。

它俩的用法基本一样,都是传入 HTML 标签名称,返回符合该 HTML 标签的数据。区别是 find() 方法只返回第一个符合条件的标签,而 find_all() 方法返回所有符合条件的标签列表。我想你从它俩的名字中便能领会到这个区别。

除了传入 HTML 标签名称 外,这两个方法还支持传入 HTML 属性 进行筛选,返回符合条件的数据。举个例子:

# 查找 id='doubanapp-tip' 的 div 标签

soup.find('div', id='doubanapp-tip')

# 查找所有 class='rating_nums' 的 span 标签

soup.find_all('span', class_='rating_nums')

Tips:因为 class 是 Python 中定义类的关键字,因此用 class_ 表示 HTML 中的 class。

Tag 对象

BeautifulSoup 将 HTML 中的元素封装成了 Tag 对象。和 BeautifulSoup 对象 一样,Tag 对象 里也有 find() 和 find_all() 方法。因此,我们可以不断地调用这两个方法,一层一层地找到我们需要的数据。我们还是以前面的 HTML 代码为例提取其中的书名:

我们可以看到,书名在 a 标签 中。但如果直接使用 soup.find_all('a') 的话,第二行的“登录/注册”和第五行的“豆瓣电影”也会被获取到,因此我们需要将这些无效数据过滤掉。

我们分析一下不难发现,书名在 class="item" 的 div 标签 里的 a 标签 内。我们只要先找到所有 class="item" 的 div 标签,然后再找到其中的 a 标签 即可,因此我们可以像下面这样来获取书名的数据:

# 找到所有 class_='item' 的 div 标签

items = soup.find_all('div', class_='item')

for i in items:

# 找到 class_='item' 的 div 标签中的 a 标签

print(i.find('a'))

# 输出:

# 追风筝的人

# 解忧杂货店

# 小王子

这样,我们就找到了所有书名的数据。此时返回的还是 Tag 对象。如果我们只想要书名和对应的链接呢?这就用到了 Tag 对象 的 text 属性和 HTML 属性名取值。

items = soup.find_all('div', class_='item')

for i in items:

tag = i.find('a')

# 获取 text 属性

name = tag.text

# 获取 href 属性值

link = tag['href']

print(name, link)

# 输出:

# 追风筝的人 https://book.douban.com/subject/1770782/

# 解忧杂货店 https://book.douban.com/subject/25862578/

# 小王子 https://book.douban.com/subject/1084336/

我们通过 Tag 对象 的 text 属性拿到了 a 标签里的文字内容,即 追风筝的人 等。然后我们通过和字典取值一样的方式,将 HTML 属性名 作为键,得到了对应属性的值。这里是以 href 属性为例,其他的 HTML 属性也同样可以。

我们来总结一下 Tag 对象 的常用属性和方法:

tag.find:返回符合条件的首个数据

tag.find_all:返回符合条件的所有数据

tag.text:获取标签的文本内容

tag['属性名']:获取HTML标签属性的值

我们通过多次调用 find() 或 find_all() 方法一层层地找到了我们需要的数据。你可能会问,有没有什么方法可以直接就找到我们需要的数据,而不用多次查找吗?

答案是肯定的,需要用到 CSS 选择器

from bs4 import BeautifulSoup

html = '''

小王子

追风筝的人

'''

soup = BeautifulSoup(html, 'html.parser')

print(soup.select('.item.book'))

# 输出:[]

print(soup.select('.item .book'))

# 输出:[

小王子

,

追风筝的人

]

print(soup.select('.item > .book'))

# 输出:[

小王子

]

BeautifulSoup 对象 有一个 select() 方法,我们将 CSS 选择器 传进去即可直接找到我们需要的元素。上面查找在 class="item" 的 div 标签里的a标签的代码就可以这样写:

items = soup.select('div.item a')

for i in items:

name = i.text

link = i['href']

print(name, link)

# 输出:

# 追风筝的人 https://book.douban.com/subject/1770782/

# 解忧杂货店 https://book.douban.com/subject/25862578/

# 小王子 https://book.douban.com/subject/1084336/

编程练习

讲解中的例子是简化过后的豆瓣读书网页源代码,接下来我们实战一下。

打开 https://book.douban.com/top250,分析它的网页源代码,用我们学过的知识点提取出书名和对应的链接。

import requests

from bs4 import BeautifulSoup

headers = {

'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.132 Safari/537.36'

}

res = requests.get('https://book.douban.com/top250', headers=headers)

soup = BeautifulSoup(res.text, 'html.parser')

items = soup.find_all('div', class_='pl2')

for i in items:

tag = i.find('a')

name = tag['title']

link = tag['href']

print(name, link)

先,使用 requests 获取了网页源代码,然后将网页源代码的字符串形式通过 BeautifulSoup 解析成了 BeautifulSoup 对象,接着我们通过 BeautifulSoup 对象 的 find() 和 find_all() 方法查找我们需要的数据。

当我们需要的数据无法一次查找到时,我们需要多次调用 find() 和 find_all() 方法来一层层查找。找到需要的数据后,就可以调用 tag.text 或 tag['属性名'] 提取到我们需要的部分了。

我们通过 ''.join(tag.text.split()) 将内容按空格符(包括空格、换行符等)分隔再拼接,这样就去除了所有的空格符。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值