使用BeautifulSoup爬取想要的标签(《python网络爬虫权威指南》笔记)
使用BeautifulSoup爬取想要的标签
- 精确爬取标签
- BeautifulSoup中的find()和find_all()方法
- BeautifulSoup中的对象
- 兄弟、子、父、后代标签的处理
- 抓取子标签和其他后代标签
- 抓取兄弟标签
- 抓取父标签
- 正则表达式
- 正则表达式和BeautifulSoup
- 获取属性
- Lambda表达式(匿名函数)
精确爬取标签
我们可以使用标签的CSS属性爬取择我们想要的一个或者多个标签,如class(类)属性、id属性、src属性等。
为了方便演示标签的选择,我们使用书中作者特别准备好的爬虫演示网站为例(http://www.pythonscraping.com/pages/warandpeace.html
)。在这个网站中,人物的对话是红色的,对应的类属性为red,人物名的标签为绿色的,对应的类属性为green,并且对应的标签都是span标签,比如:
<span class="green">the prince</span>
<span class="red">First of all, dear friend, tell me how you are. Set your friend's
mind at rest,</span>
那么我们就可以通过类属性来轻松的抓取出现的任务的名字:
from bs4 import BeautifulSoup
from urllib.request import urlopenhtml = urlopen("http://www.pythonscraping.com/pages/warandpeace.html")
bs = BeautifulSoup(html,"html.parser")
nameList = bs.find_all("span",{"class":"green"})
for name in nameList:print(name.get_text())#get_text()表示只获取标签中的文本,如果不使用该方法,#则会打印完整的标签
BeautifulSoup中的find()和find_all()方法
find()方法和find_all()方法从字面意义上就可以看出区别,find用于抓取一个符合条件的标签,find_all()则用于抓取若干(默认为全部)个符合条件的标签,他们的定义如下:
find_all(tag,attributes,recursive,text,limit,keywords)
find(tag,attributes,recursive,text,keywords)
除了参数limit,两个方法的参数含义相同,所以之后都以find_all为例子进行说明:
tag:需要查找的标签名称(或者说类型),当只查找一种标签时以字符串类型传入,当查找多种标签的时候则以列表的形式传入,比如:
.find_all(["h1","h2","h3","h4","h5","h6"])
#查找所有标题标签
attributes:用字典封装,键对应需要查找的标签的属性,值对应于属性的值,比如:
.find_all("span",{"class":"green"})
#对应查找类属性的值为green的span标签
.find_all("span",{"class":{"green","red"}})
#对应查找类属性的值为green和red的span标签,注意对比二者的区别
recursive:传入一个bool变量,当传入True(默认)的时候,会抓取所有满足条件的标签,当为False的时候,只抓取一级标签,比如我们想要抓取p标签,对于下面这个p标签就不能被抓取到,因为它被包含在div标签中:
<div><p>123</p></div>
text:按标签中的文本来抓取内容,比如对于上面被包含在div中的p标签,我们就可以使用以下代码来进行抓取:
.find_all(text="123")
limit:最多抓取符合条件的标签的数目,从HTML代码最上方开始算起,当其值为1时,功能与find()方法等价
keyword:指定被抓取的标签的属性,比如:
.find_all(id="title",class_="text")
#寻找id为title。class为text的标签
#由于class为python中受保护的关键字,在指定类属性的
#时候需要写成class_
BeautifulSoup中的对象
BeautifulSoup对象:如之前展示的那样。
Tag对象:代表从HTML中抓取到的标签,通过find()或者find_all()方法得到,或者访问BeautifulSoup的属性得到。
NavigabelString对象:代表标签中的文字。
comment对象:用于表示HTML中的注释。
兄弟、子、父、后代标签的处理
这里我们以作者提供的虚拟购物网站为例进行说明:(http://www.pythonscraping.com/pages/page3.html
)
抓取子标签和其他后代标签
在BeautifulSoup中,子标签表示父标签中包含的下一级标签,而后代标签则表示标签中包含的下一级标签、下下一级标签、下下下一级标签等等,也就是说一个标签的子标签是它的后代标签,而一个标签的后代标签不一定是它的子标签。如果我们需要查看一个标签对象的子标签,则可以使用其children属性来获得,比如:
from bs4 import BeautifulSoup
from urllib.request import urlopenhtml = urlopen("http://www.pythonscraping.com/pages/page3.html")
bs = BeautifulSoup(html,"html.parser")for children in bs.find("table",{"id":"giftList"}).children:print(children)
从上面代码我们可以看到,首先我们使用了find方法,抓取到类型为table,id为giftList的标签,之后调用其children属性获取其子标签,由于其有多个子标签,所以我们使用for循环来对其子标签进行遍历。
另外我们还可以使用descendant属性来找出所有后代标签。
抓取兄弟标签
兄弟标签即同一级的标签,在BeautifulSoup中可以使用tag对象的next_siblings来抓取改标签之后的所有兄弟标签,也可以使用previous_siblings来抓取改标签之前的所有兄弟标签。同样的,还有next_sibling和previous_sibling,用来抓取后一个或者前一个兄弟标签。下面是一个例子:
from bs4 import BeautifulSoup
from urllib.request import urlopenhtml = urlopen("http://www.pythonscraping.com/pages/page3.html")
bs = BeautifulSoup(html,"html.parser")for sibling in bs.find("table",{"id":"giftList"}).tr.next_siblings:print(sibling)#抓取div中第一个tr标签之后的所有同级标签并遍历
抓取父标签
查找抓取父标签的功能并不适用,可以使用parent和parents来抓取当前标签的父标签,下面是一个例子:
from bs4 import BeautifulSoup
from urllib.request import urlopenhtml = urlopen("http://www.pythonscraping.com/pages/page3.html")
bs = BeautifulSoup(html,"html.parser")
print(bs.find("img",{"src":"../img/gifts/img1.jpg"}).parent.previous_sibling.get_text())
最后一行代表先找到符合条件的img标签,之后选择img标签的父标签,之后在选择该父标签的之前的一个兄弟标签,获取其文本内容。
正则表达式
正则表达式在提取字符串时非常有用,它可以理解为一种字符串匹配规则,比如对于满足以下所有条件的字符串:
- 字母“a”至少出现一次
- 后面跟着“b”,重复五次
- 后面再跟着“c”,重复任意偶数次(包括零次)
- 最后一位是“d”或者“e”
满足以上规则的字符串有很多,比如“aaaabbbbbccccd”。使用正则表达式则可以表示以上的四个条件,可以表示为:
a+bbbbb(cc)*(d|e)
改正则表达式可以解释为:
- a+:+号代表前面的字符至少出现一次,如“a”或者“aaaa”
- bbbbb:5个b
- (cc)*:星号代表前面的字符至少出现0次或以上,由于加了括号,所以是两个c,所以代表c需要出现偶数次,如“cc”或者“cccc”
- (d|e):必须是d或者e,可以与其他符号如“+”号进行组合,表示可以出现一次以上的“d”或者“e”
下面是常用的正则表达式符号:
符号 | 含义 | 例子 | 可能的匹配结果 |
---|---|---|---|
* | 匹配前面的字符、表达式或者括号里的字符0次或多次 | ab | aaabbb,aaa |
+ | 匹配前面的字符、表达式或者括号里的字符至少1次 | a+b+ | ab,aabb |
[] | 匹配中括号里的任意字符(相当于选一个) | [A-Z]* | APPLE,QWERTY |
() | 表达式编组(里面的表达式优先执行) | (ab) | aabaab,abaab |
{m,n} | 匹配前面的字符、表达式或者括号里的字符m次到n次 | a{2,3}b{2,3} | aabbb,aaabbb |
[^] | 匹配任意一个不再括号中的字符 | [^A-Z]* | abc1234,qwert |
| | 匹配任意一个由竖线分隔的字符、子表达式 | b(a|i|e)d | bid,bed,bad |
. | 匹配任意单个字符 | b.d | bad,bzd |
^ | 表示以前面的字符或表达式开头 | ^a | asdf,a |
\ | 转义字符(把具有特殊含义的字符转换为字面形式) | \. \| \ \ | .|\ |
$ | 表示从字符串的末端匹配 | [A-Z] *[a-z] *$ | ABCabc,zzzyx |
?! | 不包含 | ^((?![A-Z]).)$ | no-caps-here,a4e f!ne |
\d | 表示匹配任意一个数字 | \d+ | 1,123 |
\D | 表示匹配任意一个非数字 | \D+ | ab!c,AbS |
\s | 匹配空白字符(包括\t,\n,\r和空格) | \s | |
\w | 匹配0-9,A-Z,a-z和下划线 | \w+ | abvAWE123_ |
\w | \w的补集 | \W+ | ++++===- |
正则表达式和BeautifulSoup
使用正则表达式可以让我们在抓取网页中想要的标签时更加的方便,比如还是以之前的虚拟购物网站为例子,我们可以使用正则表达式来实现批量抓取文件路径类似的图片:
from bs4 import BeautifulSoup
from urllib.request import urlopen
import rehtml = urlopen("http://www.pythonscraping.com/pages/page3.html")
bs = BeautifulSoup(html,"html.parser")images = bs.find_all("img",{"src":re.compile("\.\.\/img\/gifts\/img[0-9]*\.jpg")})
for image in images:print(image["src"])
# ../img/gifts/img1.jpg
# ../img/gifts/img2.jpg
# ../img/gifts/img3.jpg
# ../img/gifts/img4.jpg
# ../img/gifts/img6.jpg
其中re模块中的compile函数用于将字符串转化为正则表达式。
获取属性
我们可以使用一个Tag对象的attrs属性来查看该标签的所有CSS属性,以我们之前使用爬虫抓取的图片标签为例:
for image in images:print(image.attrs)
# {'src': '../img/gifts/img1.jpg'}
# {'src': '../img/gifts/img2.jpg'}
# {'src': '../img/gifts/img3.jpg'}
# {'src': '../img/gifts/img4.jpg'}
# {'src': '../img/gifts/img6.jpg'}
Lambda表达式(匿名函数)
Lambda表达式本质上是一个函数(称为匿名函数),对于find和find_all方法,允许我们将一个函数作为参数传入,该函数必须满足以下条件:
- 该函数传入的参数必须是标签对象
- 返回的值必须是bool量
之后find或者find_all函数便会将html文本中的每一个标签作为参数传入该函数,倘若返回的为True,则认为符合条件,将其以Tag对象返回,比如我们想要抓取具有两个CSS属性的标签,可以这么写:
bs.find_all(lambda tag:len(tag.attrs) == 2)
使用BeautifulSoup爬取想要的标签(《python网络爬虫权威指南》笔记)相关推荐
- 爬虫书籍-Python网络爬虫权威指南OCR库 NLTK 数据清洗 BeautifulSoup Lambda表达式 Scrapy 马尔可夫模型
Python网络爬虫权威指南 编辑推荐 适读人群 :需要抓取Web 数据的相关软件开发人员和研究人员 作为一种采集和理解网络上海量信息的方式,网页抓取技术变得越来越重要.而编写简单的自动化程序(网络爬 ...
- 股票数据定向爬取(可运行) Python网络爬虫与信息提取(北京理工大学—嵩天)
注意:由于东方财富网与百度股票网站发生变动,所以选择了与原先百度股票类似的股城网作为信息爬取的目标网站.(感谢文章:(4条消息) Python爬虫入门实例八之股票数据定向爬取并保存(优化版)_Mr.Q ...
- python爬虫爬取新闻标题及链接_网络爬虫百度新闻标题及链接爬取
1.主题:百度新闻爬取 2. python代码: import requests from bs4 import BeautifulSoup def getHTMLText(url): try: r ...
- python爬取百度新闻_火车浏览器网络爬虫实践6:以“陕茶”为例爬取百度新闻搜索结果...
每天进步一点点,这是我2019年的小目标. 这是第6次学习与实践笔记了,这一次咱们把对象转移到百度搜索去,尝试使用火车浏览器爬虫工具来采集百度新闻搜索的结果,并做简单数据可视化展示. 01 抓取需求 ...
- python网络数据爬取及分析_《Python网络数据采集》读后总结--第3章开始爬取数据及天善用户关系分析实例...
这次介绍一下<Python网络数据采集>这本书的第3章内容(Chpt03.开始爬数据的内容), 使用了天善用户关系分析的示例来介绍一下具体实践. 1.第3章内容简介 1-getWikiLi ...
- python爬取腾讯视频弹幕_网络爬虫实战(四):爬取腾讯视频电视剧弹幕-Go语言中文社区...
文章目录 实战背景 说到被翻拍最多的大概就是金庸先生的剧了,有华人的地方就会有金庸剧.而在他的多部小说中,翻拍次数最多的无疑就是<倚天屠龙记>了,而且次数已经高达十四次.最早的是1963香 ...
- python中data.find_all爬取网站为空列表_Python网络爬虫之Scrapy 框架-分布式【第二十九节】...
1. 介绍scrapy-redis框架 scrapy-redis 一个三方的基于redis的分布式爬虫框架,配合scrapy使用,让爬虫具有了分布式爬取的功能. github地址: https://g ...
- python爬取新浪博客_python网络爬虫 新浪博客篇
上次写了一个爬世纪佳缘的爬虫之后,今天再接再厉又写了一个新浪博客的爬虫.写完之后,我想了一会儿,要不要在博客园里面写个帖子记录一下,因为我觉得这份代码的含金量确实太低,有点炒冷饭的嫌疑,就是把上次的代 ...
- [day4]python网络爬虫实战:爬取美女写真图片(Scrapy版)
l> 我的新书<Android App开发入门与实战>已于2020年8月由人民邮电出版社出版,欢迎购买.点击进入详情 文章目录 1.开发环境 2.第三方库 3.Scrapy简介 4. ...
最新文章
- 【Git】Git 标签使用 ( 创建并查询标签 | 推送单个标签到远程仓库 | 推送所有标签到远程仓库 | 删除远程仓库的标签 )
- ajax传值到ashx接收反序列
- MNIST手写数字识别
- viewDidLoad、viewWillAppear、viewWillDisappear
- LeetCode 1055. 形成字符串的最短路径(贪心)
- spring boot 事务_Redis 事务在 SpringBoot 中的应用
- c语言中合法整型常量负号,C语言中整型常量的表示方法
- (附源码)ssm智慧社区管理系统 毕业设计 101635
- configure error:Package requirements (openssl) were not met
- 起风了,唯有努力以生存
- 1335 工作计划的最低难度(动态规划)
- FTPClient上传文件storeFile失败,没有异常,切换目录操作可以成功
- 软件工程读书笔记(五)——软件工程师的思维误区
- 做什么网站挣钱,这几种类型的网站可能适合你!
- 计算机与艺术传媒用英语怎么说,经济学人:艺术评论和计算机 数字图画
- 服务器ip多有什么作用是什么,使用多ip服务器有什么优势呢?
- Cris 的 Spark SQL 笔记
- Vungle 视频广告接入踩坑记
- 一元函数微分学的几何与物理应用
- 计算机图形学--全局光照(3D 空间:LPV,VXGI;屏幕空间:SSAO)
热门文章
- 强制退出当前ubuntu命令
- h1z1最新消息服务器,h1z1服务器在哪 | 手游网游页游攻略大全
- Mysql 索引为啥使用B+树?不用哈希或B树?红黑树?
- VA虚拟平台十大亮点
- sparql学习 sparql示例 dbpedia在线验证
- creo 二次开发 protookit 官方make file 案例试运行
- 驱动开发之注册表:获取注册表HKEY_CURRENT_USER对应路径(SID)
- python语言的运行效率高吗_为什么Python效率这么低,还这么火?
- 社区发现(社团检测)模块度Modularity详细介绍
- vue实现实时直播 摄像头实现实时直播 dplayer+flv flv.js