爬虫系列 | 6、详解爬虫中BeautifulSoup4的用法
bs4,全称BeautifulSoup 4
, 它是Python独有的一种解析方式。也就是说只有Python语言才可以通过这种方式去解析数据。
BeautifulSoup 3 只支持Python2,所以已经被淘汰了。
官网的介绍是这样的
Beautiful Soup 提供一些简单的、python 式的函数用来处理导航、搜索、修改分析树等功能。它是一个工具箱,通过解析文档为用户提供需要抓取的数据,因为简单,所以不需要多少代码就可以写出一个完整的应用程序。 Beautiful Soup 自动将输入文档转换为 Unicode 编码,输出文档转换为 utf-8 编码。你不需要考虑编码方式,除非文档没有指定一个编码方式,这时,Beautiful Soup 就不能自动识别编码方式了。然后,你仅仅需要说明一下原始编码方式就可以了。 Beautiful Soup 已成为和 lxml、html6lib 一样出色的 python 解释器,为用户灵活地提供不同的解析策略或强劲的速度。
看起来很复杂,我用自己的理解,通俗的解释一下
我们知道一个网页的源代码,是由多个标签组成,比如、
其他解析器的优缺点
一、bs4的安装
pip install bs4
pip install lxml
使用bs4解析时,推荐使用lxml解析器。这个在用xpath解析的时候也会用到
二、bs4解析原理
- 首先实例化一个BeautifulSoup对象,并且将页面源代码加载到这个对象里
- 调用BeautifulSoup对象中的相关属性或者方法进行标签定位和数据提取
1、如何实例化BeautifuSoup对象
a. 导入bs4包
from bs4 import BeautifulSoup
b.实例化对象
网页源代码,又分为本地已经持久化的HTML文件和网络上直接获取的源代码。
如果是本地已经持久化的文件,可以通过下面的方式将源代码加载到bs4对象中
fp = open('xxx.html', 'r', encoding='utf-8')
# lxml:解析器
soup = BeautifulSoup(fp, 'lxml')
如果是通过requests库获取的网页源代码,通过下面的方式进行加载
response = requests.get(url)
html = response.text
soup = BeautifulSoup(html, 'lxml')
c.数据解析的方法和属性
bs4能够将复杂的HTML转换成一个树形结构,每个节点都是Python对象。
soup.tagName(标签名): 返回的是文档中第一次出现tagName对应的标签及其相应内容
soup.tageName1.tageName2:返回tag1中tage2的标签及其内容
soup.find:等同于soup.tagName,返回第一个匹配到的对象
soup.find_all:返回所有的匹配到的对象。
通过查看源码会发现,find的本质其实就是调用了find_all, 然后返回第一个元素
参数解释:
- name :要查找的标签名(字符串、正则、方法、True)
- attrs: 标签的属性
- recursive: 递归
- text: 查找文本
- **kwargs :其它 键值参数
def find(self, name=None, attrs={}, recursive=True, text=None,
**kwargs):
"""Return only the first child of this Tag matching the given
criteria."""
r = None
l = self.find_all(name, attrs, recursive, text, 1, **kwargs)
if l:
r = l[0]
return r
上图是我从某网站截取的部分画面,翻译成HTML如下(只保留了对本次分析有用的部分,为了方便阅读删除了地址的域名信息)
<html>
<head><titel>测试Title</titel></head>
<body>
<div class="test">
<ul>
<li> <a href="zhaosi.html"><img src="123456789.jpg" /><p>尼古拉斯赵四</p></a> </li>
</ul>
</div>
<div class="nr_zt w1180">
<ul>
<li> <a id="star" href="zhengshuang.html"><img src="5940f2cd6b759.jpg" /><p>郑爽</p></a> </li>
<li> <a id="star" href="zhuyilong.html"><img src="5b56e0fabf5bf.jpg" /><p>朱一龙</p></a> </li>
<li> <a id="star" href="zhoudongyu.html"><img src="5a28b93be8155.jpg" /><p>周冬雨</p></a> </li>
<li> <a id="star" href="huyitian_1.html"><img src="5aa36dfbe5f61.jpg" /><p>胡一天</p></a> </li>
<li> <a id="star" href="yiyangqianxi.html"><img src="5a28d243b0382.jpg" /><p>易烊千玺</p></a> </li>
<li> <a id="star" href="dilireba.html"><img src="5a28b69334087.jpg" /><p>迪丽热巴</p></a> </li>
</ul>
</div>
</body>
</html>
看下面几个例子
# 获取第一个li标签
# <li> <a href="http://www.win4000.com/mt/zhengshuang.html"><img src="http://pic1.win4000.com/tj/2017-06-14/5940f2cd6b759.jpg"/><p>郑爽</p></a> </li>
print(soup.li)
# # 获取第一个li标签中a标签
# <a href="http://www.win4000.com/mt/zhengshuang.html"><img src="http://pic1.win4000.com/tj/2017-06-14/5940f2cd6b759.jpg"/><p>郑爽</p></a>
print(soup.li.a)
#获取第一个li标签中a标签
print(soup.find('li').a)
# 获取所有li标签
print(soup.find_all('li'))
# 获取title标签
print(soup.title)
# 获取a标签的父级标签
print(soup.a.parent)
# 获取a标签的父级标签的名字
print(soup.a.parent.name)
如何获取HTML中的href?
分析:href是a标签中的一个属性,而a标签又在li标签中
在bs4中提取标签中的属性可以通过attrs来获取
from bs4 import BeautifulSoup
fp = open('baidu.html', 'r', encoding='utf-8')
soup = BeautifulSoup(fp, 'lxml')
# 如果获取一个可以这样写
result = soup.a.attrs['href']
# zhaosi.html
print(result)
# 获取全部,可通过先获取a标签 然后遍历获取
all_result = soup.find_all('a')
for i in all_result:
print(i.attrs['href'])
print("* " * 40)
# 如果我只想获取id = star的href,需要先对id进行筛选
# 返回所有包含id=star的a标签
star_result = soup.find_all('a', id='star')
for i in star_result:
print(i.attrs['href'])
# 返回包含id的标签(只要有id属性,并且有值的标签都返回)
soup.find_all(id=True)
# 假设尼古拉斯赵四 不是第一个a标签中的内容.提取对应的href
# 需要先定位class=‘test’对应div的位置
# 方法一:
result = soup.find('div', 'test')
print(result.a['href'])
# 方法二(class为python中关键字,因此查找html中的class属性需要添加个下划线 class_)
result1 = soup.find('div', class_='test')
print(result1.a['href'])
# 方法三
result2 = soup.find('div', attrs={'class': 'test'})
# 获取第一个a标签中的文本内容
print(soup.a.text)
a_result = soup.find_all('a')
for i in a_result:
# 生成的是一个迭代器
print(i.strings)
print(list(i.strings))
print(i.string)
print(i.text)
其他补充
# 返回子孙节点
# children返回迭代器
result = soup.a.children
for i in result:
print(i)
# 返回子孙节点, contents返回列表
r = soup.a.contents
print(r)
# 可以通过正则对某个属性进行匹配
# 比如返回href中以zh开头的标签
import re
reg = re.compile('^zh')
result = soup.find_all(href=reg)
print(result)
选择器
bs4非常强大,还支持css选择器。通过select来完成
<html>
<head><titel>测试Title</titel></head>
<body>
<div class="test">
<ul>
<li> <a href="zhaosi.html"><img src="123456789.jpg" /><p>尼古拉斯赵四</p></a> </li>
</ul>
</div>
<div class="nr_zt w1180">
<ul>
<li> <a id="star" href="zhengshuang.html"><img src="5940f2cd6b759.jpg" /><p>郑爽</p></a> </li>
<li> <a id="star" href="zhuyilong.html"><img src="5b56e0fabf5bf.jpg" /><p>朱一龙</p></a> </li>
<li> <a id="star" href="zhoudongyu.html"><img src="5a28b93be8155.jpg" /><p>周冬雨</p></a> </li>
<li> <a id="star" href="huyitian_1.html"><img src="5aa36dfbe5f61.jpg" /><p>胡一天</p></a> </li>
<li> <a id="star" href="yiyangqianxi.html"><img src="5a28d243b0382.jpg" /><p>易烊千玺</p></a> </li>
<li> <a id="star" href="dilireba.html"><img src="5a28b69334087.jpg" /><p>迪丽热巴</p></a> </li>
</ul>
</div>
</body>
</html>
from bs4 import BeautifulSoup
fp = open('baidu.html', 'r', encoding='utf-8')
soup = BeautifulSoup(fp, 'lxml')
# 返回一个所有a标签的列表
result = soup.select('a')
# 返回第一个
result1 = soup.select('a')[0]
"""
class选择器 : .className
"""
# 一层一层的进行选择,用 > 连接 即 > : 表示一个层级
# 输出 class = nr_zt 下ul下的li下的a标签集合
a = soup.select('.nr_zt > ul > li > a')
# 多个层级关联,使用 空格。
# 输出 class= 'nr_zt' 下的a标签集合
b = soup.select('.nr_zt a')
"""
id选择器: # idName
"""
result = soup.select('#star')
# 通过href属性查找,返回列表
soup.select('a[href="zhengshuang.html"]')
# 获取对应标签中img标签的src值
a = soup.select('a[href="zhengshuang.html"]')[0]
print(a.img['src']) # 5940f2cd6b759.jpg
以上就是bs4的常用操作代码,实际上在具体的爬虫过程中,匹配的方式比较灵活,所以大家也不用可以的去背,只需要记住其原理即可。
爬虫系列 | 6、详解爬虫中BeautifulSoup4的用法的更多相关文章
- CSS学习笔记(9)--详解CSS中:nth-child的用法
详解CSS中:nth-child的用法 前端的哥们想必都接触过css中一个神奇的玩意,可以轻松选取你想要的标签并给与修改添加样式,是不是很给力,它就是“:nth-child”. 下面我将用几个典型的实 ...
- 爬虫系列---selenium详解
一 安装 pip install Selenium 二 安装驱动 chrome驱动文件:点击下载chromedriver (yueyu下载) 三 配置chromedrive的路径(仅添加环境变量即可) ...
- Python Deque 模块使用详解,python中yield的用法详解
Deque模块是Python标准库collections中的一项. 它提供了两端都可以操作的序列, 这意味着, 你可以在序列前后都执行添加或删除. https://blog.csdn.net/qq_3 ...
- Python爬虫系列-Selenium详解
自动化测试工具,支持多种浏览器.爬虫中主要用来解决JavaScript渲染的问题. 用法讲解 模拟百度搜索网站过程: from selenium import webdriver from selen ...
- Python爬虫系列-BeautifulSoup详解
安装 pip3 install beautifulsoup4 解析库 解析器 使用方法 优势 劣势 Python标准库 BeautifulSoup(markup,'html,parser') Pyth ...
- Python爬虫系列-PyQuery详解
强大又灵活的网页解析库.如果你觉得正则写起来太麻烦,如果你觉得BeautifulSoup语法太难记,如果你熟悉jQuery的语法,那么PyQuery就是你的最佳选择. 安装 pip3 install ...
- 详解CSS中:nth-child的用法
前端的哥们想必都接触过css中一个神奇的玩意,可以轻松选取你想要的标签并给与修改添加样式,是不是很给力,它就是“:nth-child”. 下面我将用几个典型的实例来给大家讲解:nth-child的实际 ...
- 详解Lombok中的@Builder用法
Builder 使用创建者模式又叫建造者模式.简单来说,就是一步步创建一个对象,它对用户屏蔽了里面构建的细节,但却可以精细地控制对象的构造过程. 基础使用 @Builder注释为你的类生成相对略微复杂 ...
- 反爬虫:利用ASP.NET MVC的Filter和缓存(入坑出坑) C#中缓存的使用 C#操作redis WPF 控件库——可拖动选项卡的TabControl 【Bootstrap系列】详解Bootstrap-table AutoFac event 和delegate的分别 常见的异步方式async 和 await C# Task用法 c#源码的执行过程
反爬虫:利用ASP.NET MVC的Filter和缓存(入坑出坑) 背景介绍: 为了平衡社区成员的贡献和索取,一起帮引入了帮帮币.当用户积分(帮帮点)达到一定数额之后,就会“掉落”一定数量的“帮帮 ...
- python 3.x 爬虫基础---Urllib详解
python 3.x 爬虫基础 python 3.x 爬虫基础---http headers详解 python 3.x 爬虫基础---Urllib详解 前言 爬虫也了解了一段时间了希望在半个月的时间内 ...
随机推荐
- 使用spark将内存中的数据写入到hive表中
使用spark将内存中的数据写入到hive表中 hive-site.xml <?xml version="1.0" encoding="UTF-8" st ...
- Maven项目中配置jdk版本
<build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> ...
- sychronized的实现原理和应用
一.synchronized的使用 1.1修饰方法 public synchronized void method() { // todo } 1.2修饰代码块 public void run() { ...
- [IOI1994]The Castle
开了博客之后一直没动今天水完题手痒想起这个就来水一篇陈年水题(雾 题目链接<< 题意:给一张n*m个格子的地图信息,求连通块个数以及最大连通块面积. 每个格子四个方向可以有墙,输入用一个十 ...
- layui的登录页面设计
主要的结构 先导入layui的主要的js和css等 <html> <head> <meta charset="utf-8"> <title ...
- 【基础】CentOS6如何将命令行模式下安装图形界面
系统版本:这里我使用的系统是CentOS6.9 安装方式:安装方式为yum源安装 1.配置yum源仓库 # 在配置之前最好把我们自己的yum仓库文件备份一下: cp /etc/yum.repos.d/ ...
- easyui中开始时间小于结束时间 不然无法点击
<tr> <td align="right">用药开始时间:</td> <td><input id="time_fr ...
- 关于char是否能表示一个中文
char是可以表示中文的 这个问题点有3个考核点 1 char是多少位的 2 java用的是什么方式表示字符 3 Unicode是用多少位表示的 1的答案是16位的,2的答案是Unicode,3的答案 ...
- eclipse中安装jetty插件并使用
一.eclipse中jetty插件安装: 打开eclipse,依次点击菜单Help->Eclipse Marketplace,在Find后面的框中输入jetty,选择第一项进行install即可 ...
- Beta冲刺--总结随笔
一.项目预期计划 时间 (天) 预期计划 完成情况 1-2 登录注册页面美化 完成 3-5 完善寻/失物登记以及管理页面 完成 6-9 实现剩下的用户管理.我的账号等页面 50% 9-10 最终测试与 ...