Beautiful Soup基础入门
发布日期:2021-05-08 15:41:33 浏览次数:12 分类:精选文章

本文共 5208 字,大约阅读时间需要 17 分钟。

Beautiful Soup基础入门


  • Requests 库
  • 遍历文档树
  • 搜索文档树
  • 标签基本元素
  • Beautiful Soup 库解析器

一、Beautiful Soup简介

就是一个可以从HTML或XML文件中提取数据的Python库。实例:在最好大学网爬取2021年软科类世界大学排名的数据。

二、基本步骤

用chrome浏览器去访问该网站,然后审查元素,定位相关信息对应的代码。整个实验的关键就在于如何遍历tbody标签的孩子标签,获取tr标签里的td标签的数据。

确定好之后,接下来使用requests.get()来获取整个页面的内容。用import requests来导入Requests库。

1、准备工作

import requestsr = requests.get("https://labfile.oss.aliyuncs.com/courses/2184/2019%E8%BD%AF%E7%A7%91%E4%B8%96%E7%95%8C%E5%A4%A7%E5%AD%A6%E5%AD%A6%E6%9C%AF%E6%8E%92%E5%90%8D.html")print(r.status_code)  #检查状态码#200print(r.encoding)   #检查编码方式#ISO-8859-1r.encoding = r.apparent_encoding   #修改编码print(r.encoding)#utf-8

2、获取相应信息

r.text #获取整个页面内容

r.headers #获取页面头信息

html = r.textprint(html)#输出html代码header = r.headersprint(header)'''{'Server': 'AliyunOSS', 'Date': 'Thu, 29 Apr 2021 12:38:13 GMT', 'Content-Type': 'text/html', 'Transfer-Encoding': 'chunked', 'Connection': 'keep-alive', 'Vary': 'Accept-Encoding', 'x-oss-request-id': '608AA8B555A1A637340A18C1', 'Last-Modified': 'Fri, 24 Apr 2020 08:55:54 GMT', 'x-oss-object-type': 'Normal', 'x-oss-hash-crc64ecma': '15463410703954662493', 'x-oss-storage-class': 'Standard', 'Cache-Control': 'no-cache', 'Content-MD5': 'UT34YnbEGFbQ5LT+UwuhyA==', 'x-oss-server-time': '15', 'Content-Encoding': 'gzip'}'''

3、解析HTML页面

Beautiful Soup库有专门的解析器,解析器的作用简单来说,就是用来解析和提取HTML或XML页面的数据。它有四种解析器:

第一种Python自带,后三种需自行安装

python标准库

lxml HTML解析器

lxml XML 解析器

html5lib

下面使用python标准库的解析器,使用 from bs4 import BeautifulSoup 导入 BeautifulSoup 库。使用 BeautifulSoup(markup, "html.parser") 去解析页面。

from bs4 import BeautifulSoupsoup = BeautifulSoup(html, "html.parser")print(soup)#返回有格式的html代码

4、遍历和搜索文档树

3-3 html 标签树

每个标签都有一个名字,每个标签可以有0个或者多个属性,标签之间的字符串是非属性字符串或者注释,如下图所示:

图 3-4 标签的基本元素

我们的实验任务是要获取页面上的三类数据,分别是学校排名、学校名字和学校总分。所以,我们需要遍历标签树,搜索到这三类数据并保存到列表中。从上面的内容我们已经知道,所需要的数据是在 tbody 的子标签里,所以我们需要使用 find() 去遍历 tbody 标签的孩子标签。

data = soup.find("tbody").childrenprint(data)#输出tbody标签的子节点(是一个迭代器)

上面的代码中,find() 是搜索文档树中的一种方法,它能够返回第一个匹配的元素。它的完整参数形式为:find( name , attrs , recursive , string , **kwargs )。参数 name 是用标签名去检索字符串,参数 attrs 是用标签属性值去检索字符串,参数 recursive 是否对子孙全部检索,默认为 True,参数 string 是检索标签中的非属性字符串。

.children 是标签下行遍历的一种属性。标签一共有三种遍历形式,分别是下行遍历、上行遍历和平行遍历。

下行遍历的三个属性:

  • .children 是循环遍历儿子节点
  • .descendants 是循环遍历所有子孙节点
  • .contents 是将该标签中所有儿子节点存入列表

上行遍历有以下两个属性:

  • .parent 是访问该节点的父节点标签
  • .parents 是循环遍历所有先辈节点

平行遍历有以下四个属性:

  • .next_sibling 是返回下一个平行节点的标签
  • .previous_sibling 是返回上一个平行节点的标签
  • .next_siblings 是返回后面所有平行节点的标签
  • .previous_siblings 是返回前面所有平行节点的标签

现在我们已经获取了 tbody 标签中所有孩子标签了,由于返回的是一个迭代器,你可以使用 list(data) 以列表的形式输出看一看获取到的数据结果。我们这里直接使用 for 语句去遍历 tr 标签。

for tr in data:	print(tr)#返回所有tr标签

运行结果后,可以看到每一对 tr 标签都被遍历了,但是我们需要的td标签中的非属性字符串。这里使用 isinstance(tr, bs4.element.Tag) 去判断 tr 是否是 bs4 标签类型的元素。再用搜索文档树的另一种方法 find_all() 查询到所有td标签并保存到列表 tds 里。

import bs4info = []for tr in soup.find('tbody').children:    if isinstance(tr, bs4.element.Tag):        tds = tr.findall('td')        info.append([tds[0].string, tds[1].string, tds[4].string])print(info)'''[['1', '哈佛大学', '100.0'], ['2', '斯坦福大学', '75.1'], ['3', '剑桥大学', '72.3'], ['4', '麻省理工学院', '69.0'], ['5', '加州大学-伯克利', '67.9'], ['6', '普林斯顿大学', '60.0'], ['7', '牛津大学', '59.7'], ['8', '哥伦比亚大学', '59.1'], ['9', '加州理工学院', '58.6'], ['10', '芝加哥大学', '55.1'], ['11', '加州大学-洛杉矶', '50.8'], ['11', '耶鲁大学', '50.8'], ......]'''

find_all() 它能够查询所有符合条件的元素,以列表的形式返回查询结果。它的完整参数形式与 find() 相同,这里就不在赘述了,若忘记,请回看以上内容。现在所有的 td 标签都保存在 tds 里面,我们用 tag.string 去取出标签中的非属性字符串。这是 Tag 标签的基本属性之一,称为 NavigableString

完整代码

import requestsimport bs4 import BeautifulSoupimport bs4r = requests.get("https://labfile.oss.aliyuncs.com/courses/2184/2019%E8%BD%AF%E7%A7%91%E4%B8%96%E7%95%8C%E5%A4%A7%E5%AD%A6%E5%AD%A6%E6%9C%AF%E6%8E%92%E5%90%8D.html")   r.encoding = r.apparent_encoding        #更改编码html = r.text           #获取文本信息soup = BeautifulSoup(html, "html.parser")      #解析文本data = soup.find("tbody").children             #找出tbody标签的所有子标签(返回一个迭代器)info = []for tr in soup.find('tbody').children:    if isinstance(tr, bs4.element.Tag):    #isinstance判断某个对象是否是某个类型        tds = tr.find_all('td')    #查询所有td标签,并以列表形式返回        info.append([tds[0].string, tds[1].string, tds[4].string])   #取出标签中的非属性字符串print(info)

三、实例

爬取课程名称:

image-20210430090858625

import requestsimport bs4from bs4 import BeautifulSouptry:    url = "https://www.lanqiao.cn/courses/"    r = requests.get(url)    print(r.raise_for_status)    #返回响应状态码    r.encoding = r.apparent_encoding   #将编码修改为utf-8    demo = r.text    #获取返回的页面    #print(demo)except:    print("未能获取页面内容")    soup = BeautifulSoup(demo, 'html.parser')  #对页面进行解析div = soup.find('body').div        #获取页面body标签中的div标签a = div.find_all('a','link block')   #获取class='link block'的a标签href_list = []   #设置一个存放课程链接的列表div_list = []    #设置一个存放含有课程名称的div标签for i in a:    href_list.append("https://www.lanqiao.cn"+i.get('href'))  #向列表中填充课程链接(https://...+i.get('href'))    div_list.append(i.find('div', 'course-cover relative'))  #向列表中填充含有课程名的div标签#print(href_list)#print(div_list)img_list = []   #用于存放img标签names = []          #用于存放课程名info_dict = {   }     #用于存放课程名与链接的映射字典for i in div_list:    img_list.append(i.find('img'))for i in img_list:    names.append(i.get('alt'))for i in range(0, len(names)):    info_dict[names[i]] = href_list[i]    print(info_dict)

image-20210430100528944

学完两个爬虫实例了,感觉重点在于对返回页面的结构分析上,还有遍历和取数据的一个思路。以前都是零散的学,现在算是系统的学了一边,麻雀虽小五脏俱全,基本的思路算是掌握了。

上一篇:Django实现文件分享系统
下一篇:数据加密技术,风奥科技数据加密技术基本概述

发表评论

最新留言

感谢大佬
[***.8.128.20]2025年03月23日 21时02分55秒