使用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标签的父标签,之后在选择该父标签的之前的一个兄弟标签,获取其文本内容。

正则表达式

正则表达式在提取字符串时非常有用,它可以理解为一种字符串匹配规则,比如对于满足以下所有条件的字符串:

  1. 字母“a”至少出现一次
  2. 后面跟着“b”,重复五次
  3. 后面再跟着“c”,重复任意偶数次(包括零次)
  4. 最后一位是“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 表示匹配任意一个数字 &#92d+ 1,123
\D 表示匹配任意一个非数字 &#92D+ 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方法,允许我们将一个函数作为参数传入,该函数必须满足以下条件:

  1. 该函数传入的参数必须是标签对象
  2. 返回的值必须是bool量

之后find或者find_all函数便会将html文本中的每一个标签作为参数传入该函数,倘若返回的为True,则认为符合条件,将其以Tag对象返回,比如我们想要抓取具有两个CSS属性的标签,可以这么写:

bs.find_all(lambda tag:len(tag.attrs) == 2)

使用BeautifulSoup爬取想要的标签(《python网络爬虫权威指南》笔记)相关推荐

  1. 爬虫书籍-Python网络爬虫权威指南OCR库 NLTK 数据清洗 BeautifulSoup Lambda表达式 Scrapy 马尔可夫模型

    Python网络爬虫权威指南 编辑推荐 适读人群 :需要抓取Web 数据的相关软件开发人员和研究人员 作为一种采集和理解网络上海量信息的方式,网页抓取技术变得越来越重要.而编写简单的自动化程序(网络爬 ...

  2. 股票数据定向爬取(可运行) Python网络爬虫与信息提取(北京理工大学—嵩天)

    注意:由于东方财富网与百度股票网站发生变动,所以选择了与原先百度股票类似的股城网作为信息爬取的目标网站.(感谢文章:(4条消息) Python爬虫入门实例八之股票数据定向爬取并保存(优化版)_Mr.Q ...

  3. python爬虫爬取新闻标题及链接_网络爬虫百度新闻标题及链接爬取

    1.主题:百度新闻爬取 2. python代码: import requests from bs4 import BeautifulSoup def getHTMLText(url): try: r ...

  4. python爬取百度新闻_火车浏览器网络爬虫实践6:以“陕茶”为例爬取百度新闻搜索结果...

    每天进步一点点,这是我2019年的小目标. 这是第6次学习与实践笔记了,这一次咱们把对象转移到百度搜索去,尝试使用火车浏览器爬虫工具来采集百度新闻搜索的结果,并做简单数据可视化展示. 01 抓取需求 ...

  5. python网络数据爬取及分析_《Python网络数据采集》读后总结--第3章开始爬取数据及天善用户关系分析实例...

    这次介绍一下<Python网络数据采集>这本书的第3章内容(Chpt03.开始爬数据的内容), 使用了天善用户关系分析的示例来介绍一下具体实践. 1.第3章内容简介 1-getWikiLi ...

  6. python爬取腾讯视频弹幕_网络爬虫实战(四):爬取腾讯视频电视剧弹幕-Go语言中文社区...

    文章目录 实战背景 说到被翻拍最多的大概就是金庸先生的剧了,有华人的地方就会有金庸剧.而在他的多部小说中,翻拍次数最多的无疑就是<倚天屠龙记>了,而且次数已经高达十四次.最早的是1963香 ...

  7. python中data.find_all爬取网站为空列表_Python网络爬虫之Scrapy 框架-分布式【第二十九节】...

    1. 介绍scrapy-redis框架 scrapy-redis 一个三方的基于redis的分布式爬虫框架,配合scrapy使用,让爬虫具有了分布式爬取的功能. github地址: https://g ...

  8. python爬取新浪博客_python网络爬虫 新浪博客篇

    上次写了一个爬世纪佳缘的爬虫之后,今天再接再厉又写了一个新浪博客的爬虫.写完之后,我想了一会儿,要不要在博客园里面写个帖子记录一下,因为我觉得这份代码的含金量确实太低,有点炒冷饭的嫌疑,就是把上次的代 ...

  9. [day4]python网络爬虫实战:爬取美女写真图片(Scrapy版)

    l> 我的新书<Android App开发入门与实战>已于2020年8月由人民邮电出版社出版,欢迎购买.点击进入详情 文章目录 1.开发环境 2.第三方库 3.Scrapy简介 4. ...

最新文章

  1. 【Git】Git 标签使用 ( 创建并查询标签 | 推送单个标签到远程仓库 | 推送所有标签到远程仓库 | 删除远程仓库的标签 )
  2. ajax传值到ashx接收反序列
  3. MNIST手写数字识别
  4. viewDidLoad、viewWillAppear、viewWillDisappear
  5. LeetCode 1055. 形成字符串的最短路径(贪心)
  6. spring boot 事务_Redis 事务在 SpringBoot 中的应用
  7. c语言中合法整型常量负号,C语言中整型常量的表示方法
  8. (附源码)ssm智慧社区管理系统 毕业设计 101635
  9. configure error:Package requirements (openssl) were not met
  10. 起风了,唯有努力以生存
  11. 1335 工作计划的最低难度(动态规划)
  12. FTPClient上传文件storeFile失败,没有异常,切换目录操作可以成功
  13. 软件工程读书笔记(五)——软件工程师的思维误区
  14. 做什么网站挣钱,这几种类型的网站可能适合你!
  15. 计算机与艺术传媒用英语怎么说,经济学人:艺术评论和计算机 数字图画
  16. 服务器ip多有什么作用是什么,使用多ip服务器有什么优势呢?
  17. Cris 的 Spark SQL 笔记
  18. Vungle 视频广告接入踩坑记
  19. 一元函数微分学的几何与物理应用
  20. 计算机图形学--全局光照(3D 空间:LPV,VXGI;屏幕空间:SSAO)

热门文章

  1. 强制退出当前ubuntu命令
  2. h1z1最新消息服务器,h1z1服务器在哪 | 手游网游页游攻略大全
  3. Mysql 索引为啥使用B+树?不用哈希或B树?红黑树?
  4. VA虚拟平台十大亮点
  5. sparql学习 sparql示例 dbpedia在线验证
  6. creo 二次开发 protookit 官方make file 案例试运行
  7. 驱动开发之注册表:获取注册表HKEY_CURRENT_USER对应路径(SID)
  8. python语言的运行效率高吗_为什么Python效率这么低,还这么火?
  9. 社区发现(社团检测)模块度Modularity详细介绍
  10. vue实现实时直播 摄像头实现实时直播 dplayer+flv flv.js