这一次我们继续来讲一下BeautifulSoup的相关知识,说一下BeautifulSoup导航树的相关内容。

在上一次的博客中我们了解到findAll函数通过标签的名称和属性来查找标签,但有的时候在进网页中的内容爬取时,我们会发现有些我们想要获取的元素并不是都可以通过名称来获得的,因为我们要考虑到有些网站在编写的时候,只有一些需要特殊效果的标签会进行属性值的设置,而有些普通的标签是不会进行属性值的设置的,所以我们会遇到这种情况:当我们想要抓取一些标签中的内容时,我们在对源码进行分析时发现它的标签并没有设置class、type这些容易我们使用findAll函数的值,那我们这个时候如果强行使用findAll,很可能会抓取到很多无用的标签,这会增大我们后期的分析难度,是不可取的,这个时候我们便需要通过其它特性进行标签 的抓取了。我们其实可以通过抓取其它带有特定属性的标签,然后通过这个标签和我们目标标签之间的关系进行转化,然后得到我们想要的标签。这个可以理解为两种解决问题的方法啊,在我们解答数学题的时候经常会用到的,这就是有的问题我们可以通过直接求解进行解答,但有的问题需要通过间接求解然后进行相应的转化才能得到最终的结果,下面我们就来看看导航树给我们带来的一些功能。

顾名思义啊,导航树是一棵树。从我们现实世界中出发,树就是树干和树枝组成,当然作为一个抽象化成一种方法的树,导航树比现实世界中的树的枝和干要多很多,是一棵非常丰满的树,有很多的枝干。导航树就是将HTML页面映射成一棵树,这棵树分别在横向和纵向进行延伸,横向延伸的都是同级的标签,比如说一个ul标签中包含很多的li标签,这些li标签就是同级的;纵向延伸的是不同级的标签,其关系就是父与子的关系,包含与被包含的关系。

下面是豆瓣首页中源码的一个简洁的截图:

在上图中我们可以看到,body下有子节点div,div下还有div标签组,div下还包含div标签组,之后div包含li标签组。

下面我们就以这个HTML标签结构为例进行解说:

1、处理子标签和其它后代标签

在BeautifulSoup中,孩子标签和后代标签与我们现实社会的人类的家谱是一样的,子标签是一个父标签的下一级,而后代标签是指一个父标签下面所有级别的标签。例如,在我们刚刚选择的源码中,ul是div的子标签,而ul、li和a则都是div标签的后代标签。所有的子标签都是后代标签,但不是所有的后代标签都是子标签。

在BeautifulSoup中,它的函数总是处理当前标签的后代标签,并不会处理其它的标签,正如我们前面的博客中说过的,bsObj.body.div这段代码是会选择body部分的div进行查找,并不会跑到body外面(如head)的区域进行查找的,就像你在学校选定了计科院进行查找一个人的时候,是绝对不会查找别的院的。

比如说我们只想拿到豆瓣中每部电影的那个源码(可以用来后期解析使用),如下图所示,我们想要得到奇异博士这部影片在网页中这个框的区域所有的源码,在右边的源码汇总我们可以看出,这是存放在一个ul中的,可是我们会发现这个ul没有带什么属性,那么我们尝试使用以前的代码试一试。

程序如下:

#coding:utf - 8
from urllib.request import urlopen
from bs4 import BeautifulSouphtml = urlopen("https://movie.douban.com/")
bsObj=BeautifulSoup(html,"lxml")    #将html对象转化为BeautifulSoup对象
ulList=bsObj.findAll("ul")    #找到所有ul
for ul in ulList:print(ul)

程序运行结果如下:

<ul>
<li class="">
<a data-moreurl-dict='{"from":"top-nav-click-main","uid":"0"}' href="https://www.douban.com/" target="_blank">
              豆瓣
            </a>
</li>
<li class="">
<a data-moreurl-dict='{"from":"top-nav-click-book","uid":"0"}' href="https://book.douban.com/" target="_blank">
              读书
            </a>
</li>
<li class="on">
<a data-moreurl-dict='{"from":"top-nav-click-movie","uid":"0"}' href="https://movie.douban.com/">
              电影
            </a>
</li>
<li class="">
<a data-moreurl-dict='{"from":"top-nav-click-music","uid":"0"}' href="https://music.douban.com/" target="_blank">
              音乐
            </a>
</li>
<li class="">
<a data-moreurl-dict='{"from":"top-nav-click-location","uid":"0"}' href="https://www.douban.com/location/" target="_blank">
              同城
            </a>
</li>
<li class="">
<a data-moreurl-dict='{"from":"top-nav-click-group","uid":"0"}' href="https://www.douban.com/group/" target="_blank">
              小组
            </a>
</li>
<li class="">
<a data-moreurl-dict='{"from":"top-nav-click-read","uid":"0"}' href="https://read.douban.com/?dcs=top-nav&amp;dcm=douban" target="_blank">
              阅读
            </a>
</li>
<li class="">
<a data-moreurl-dict='{"from":"top-nav-click-fm","uid":"0"}' href="https://douban.fm/?from_=shire_top_nav" target="_blank">
              FM
            </a>
</li>
<li class="">
<a data-moreurl-dict='{"from":"top-nav-click-commodity","uid":"0"}' href="https://dongxi.douban.com/?dcs=top-nav&amp;dcm=douban" target="_blank">
              东西
            </a>
</li>
<li class="">
<a data-moreurl-dict='{"from":"top-nav-click-market","uid":"0"}' href="https://market.douban.com/?utm_campaign=douban_top_nav&amp;utm_source=douban&amp;utm_medium=pc_web" target="_blank">
              市集
            </a>
</li>
<li>
<a class="bn-more" href="#more"><span>更多</span></a>
<div class="more-items">
<table cellpadding="0" cellspacing="0">
<tr><td><a data-moreurl-dict='{"from":"top-nav-click-moment","uid":"0"}' href="https://moment.douban.com" target="_blank">一刻</a></td></tr>
<tr><td><a data-moreurl-dict='{"from":"top-nav-click-ypy","uid":"0"}' href="https://ypy.douban.com" target="_blank">豆瓣摄影</a></td></tr>
</table>
</div>
</li>
</ul>
。。。。。。

从上面的结果我们可以发现,不对啊,怎么会有一个ul显示的内容不是我们想要的关于电影的一些信息,这时候我们回到网页的源码中进行查看,会看到如下的ul,是不符合我们的需求的,如下图所示:

这时我们会发现,有个多余的ul是我们不想要的,其实这种情况在我们以后的爬取过程中会经常发生的,这就需要我们解决了,最好的方法就是在爬取的时候就把这些无用的信息扔掉,而不是在拿到手后进行处理,要做到防范于未然嘛,预防总比治疗来得轻松嘛。

那我们到网页中去看看,有什么可以解决的方法呢,然后我们可以看到ul的父亲节点是有属性的,这就是我们的突破点了,如下图:

修改后的程序如下

#coding:utf - 8
from urllib.request import urlopen
from bs4 import BeautifulSouphtml = urlopen("https://movie.douban.com/")
bsObj=BeautifulSoup(html,"lxml")    #将html对象转化为BeautifulSoup对象
liList=bsObj.findAll("li",{"class":"ui-slide-item"})    #找到所有li
for li in liList:ul=li.children     #由于children是个孩子集合,所以下面要迭代进行查看for child in ul:print(child)

程序运行如下:

<ul class="">
<li class="poster">
<a href="https://movie.douban.com/subject/26630781/?from=showing" οnclick="moreurl(this, {from:'mv_a_pst'})">
<img alt="我不是潘金莲" class="" rel="nofollow" src="https://img3.doubanio.com/view/movie_poster_cover/lpst/public/p2378133884.jpg"/>
</a>
</li>
<li class="title">
<a class="" href="https://movie.douban.com/subject/26630781/?from=showing" οnclick="moreurl(this, {from:'mv_a_tl'})">我不是潘金莲</a>
</li>
<li class="rating">
<span class="rating-star allstar35"></span><span class="subject-rate">7.1</span>
</li>
<li class="ticket_btn"><span><a href="https://movie.douban.com/subject/26630781/cinema/" οnclick="moreurl(this, {from:'mv_b_tc'})">选座购票</a></span></li>
</ul>

。。。。。。。

这次是不是就不会有多余的了,比较细心的同学有可能会发现在这个网页中这些ul的class并不都是ui-slide-item,有的是"ui-slide-item s",这个问题可能是网站的显示问题啊,因为在我们抓取到 的网页源码上就不是这样了,当然有兴趣的可以去研究下为什么。

这样我们就拿到了这些电影的整体信息了,那我们要想对它们做分析是不是就很简单了

2、处理兄弟标签

BeautifulSoup可以使用next_siblings()函数处理一些处理相同等级的相同标签,就像我们刚刚拿到的ul中的li标签,满足这一个性质,我们可以通过next_siblings()函数进行处理。

这次我们就处理夺路而逃这个电影中的li,以便于理解:

#coding:utf - 8
from urllib.request import urlopen
from bs4 import BeautifulSouphtml = urlopen("https://movie.douban.com/")
bsObj=BeautifulSoup(html,"lxml")    #将html对象转化为BeautifulSoup对象
li=bsObj.find("li",{"data-title":"夺路而逃"})    #找到符合条件的li
for li1 in li.li.next_siblings:print(li1)

程序运行如下:

<li class="title">
<a class="" href="https://movie.douban.com/subject/26125842/?from=showing" οnclick="moreurl(this, {from:'mv_a_tl'})">夺路而逃</a>
</li>

<li class="rating">
<span class="text-tip">暂无评分</span>
</li>

<li class="ticket_btn"><span><a href="https://movie.douban.com/subject/26125842/cinema/" οnclick="moreurl(this, {from:'mv_b_tc'})">选座购票</a></span></li>

这里我们会发现,咦,一共有四个li标签,为什么少了一个,那是因为一个li标签 不能将自己作为自己的兄弟标签,所以第一条li被跳过了,这里我们只是为了 演示这个next_siblings的用法,当然这个方法对于表格处理是很有效果的,因为 表格的第一行是提示的文字信息,我们在处理 表格数据时是不需要的,那么这个next_siblings就起到作用了。

和next_siblings一样,如果你很容易找到一组兄弟标签的最后一个标签,那么previous_siblings函数也会很有用。与此对应的还有next_sibling和previous_sibling,它们与next_siblings和previous_siblings作用类似,只是它们返回的是单个标签,而不是一组标签。

3、父标签处理

在抓取网页的时候,我们一般想要得到的都是一些子标签,因为父标签一般是为了模块更好的展示进行合并的一种表示方法,只是一个框架,对于我们的用处是不大的,但是有些 时候我们也是可能会用到的,比如说上面在找ul时,我们可以通过带class属性的子标签来得到这个父标签ul,父标签可以为parent和parents。

程序如下图:

#coding:utf - 8
from urllib.request import urlopen
from bs4 import BeautifulSouphtml = urlopen("https://movie.douban.com/")
bsObj=BeautifulSoup(html,"lxml")    #将html对象转化为BeautifulSoup对象
liList=bsObj.findAll("li",{"class":"poster"})    #找到所有li
for li in liList:ul=li.parentprint(ul)

运行结果就不贴了 ,还是一样的。

这样我们就讲完了导航树了,这些方法如何适当使用在我们的爬虫中,还是可以起到很好的效果的。

python3实现网络爬虫(4)--BeautifulSoup使用(3)相关推荐

  1. [Python从零到壹] 五.网络爬虫之BeautifulSoup基础语法万字详解

    欢迎大家来到"Python从零到壹",在这里我将分享约200篇Python系列文章,带大家一起去学习和玩耍,看看Python这个有趣的世界.所有文章都将结合案例.代码和作者的经验讲 ...

  2. 关于使用Python3进行网络爬虫的字符问题

    使用Python3进行网络爬虫的时候,对于某一些网页,使用utf-8编码是没有问题的.比如: import urllib.request url = "https://www.baidu.c ...

  3. 网络爬虫之BeautifulSoup和lxml

    网络爬虫之BeautifulSoup和lxml 一.网络爬虫的概念 1.1 爬虫概念 1.1.1 什么是爬虫 1.1.2 为什么学习爬虫? 1.2 爬虫流程 二.爬虫常用包 2.1 Requests包 ...

  4. python3.6网络爬虫_python3.6网络爬虫

    <精通Python网络爬虫:核心技术.框架与项目实战>--导读 前 言 为什么写这本书 网络爬虫其实很早就出现了,最开始网络爬虫主要应用在各种搜索引擎中.在搜索引擎中,主要使用通用网络爬虫 ...

  5. Python3.5 网络爬虫简单入门

    一.网络爬虫简单介绍 网络爬虫(又被称为网页蜘蛛,网络机器人),是一种按照一定的规则,自动地抓取万维网信息的程序或者脚本.另外一些不常使用的名字还有蚂蚁.自动索引.模拟程序或者蠕虫. 相对于通用网络爬 ...

  6. 没有网络怎么学网络爬虫之BeautifulSoup爬取html表格存入Excel表格

    学习网络爬虫当然是不可能一点网都没有的,我们前期需要网络打开自己需要的网页,获取网页上的源码保存在本地文件,就可以不用网络了,我家里的网络很差,我就是这样操作的,例如上节爬取智联招聘网步骤,下次访问的 ...

  7. Python网络爬虫使用BeautifulSoup爬取网页内容并存入数据库案例

    使用BeautifulSoup爬取网页内容并存入数据库案例 学习了Python网络爬虫,完成里一个比较完整的爬虫案例与大家分享 爬取地址:http://www.tipdm.com/cpzx/index ...

  8. Python3 03 网络爬虫 <下载漫画>

    @ 我的老师:Jack Cui PS:我是通过 看 Jack Cui 老师的文章 学习的爬虫,也为我之后的 爬虫打开了大门. 3.1 下载漫画 那么这一节,我们就要 去网络上下载漫画.即 图片 的爬取 ...

  9. Python3 大型网络爬虫实战 004 — scrapy 大型静态商城网站爬虫项目编写及数据写入数据库实战 — 实战:爬取淘宝

    原博文链接:http://www.aobosir.com/blog/2016/12/26/python3-large-web-crawler-taobao-com-import-to-MySQL-da ...

  10. Python3编写网络爬虫10-数据存储方式三-CSV文件存储

    3.CSV文件存储 CSV 全称 Comma-Separated Values 中文叫做逗号分隔值或者字符分隔值,文件以纯文本形式存储表格数据. 文件是一个字符序列 可以由任意数目的记录组成相当于一个 ...

最新文章

  1. 本科刚毕业有点迷茫,想入门单片机,应该怎么开始?
  2. cygwin中写c语言程序,在windows下怎么利用Cygwin进行编程
  3. 如果让学生轻松过关,他们就对老师心存轻蔑
  4. Leetcode第286场周赛
  5. linux git ssh_Git年满13岁,可以了解Linux和SSH命令,Python编程等等
  6. 团队作业4——第一次项目冲刺(Alpha版本)第三天
  7. 11. 搭建一个完整的K8S集群
  8. 天才?骗子?解析Deep Tech
  9. 【剑指 offer】(二十二)—— 栈的压入、弹出序列
  10. linux lilo命令,lilo命令_Linux lilo 命令用法详解:安装核心载入开机管理程序
  11. WASCE (基于geronimo ) 配置
  12. php dingo和jwt,三、Laravel5.4+Dingo+JWT 开发API
  13. Java虚拟机JVM简介与理解(三)
  14. MATLAB绘图(一)
  15. JAVA中的protected的访问权限只有在本类同包类和子类吗?
  16. 人为何会生病?(1)
  17. 凡科建站,PageAdmin,易极赞等自助建站系统的区别
  18. 无法启动此程序因为计算机中丢失d3dx941,d3dx_941.dll最新版
  19. Flink程序启动报错could not be determined automatically
  20. WPF 项目开发入门(三)WPF 窗体与页面

热门文章

  1. 写一个搜索引擎系统(Java版)
  2. 电赛总结(四)——波形发生芯片总结之AD9854
  3. 云服务器/树莓派搭建我的世界Minecraft多人游戏服务器
  4. 三星Galaxy Note 10.1刷机教程
  5. Don't Starve,好脚本,好欢乐
  6. “蔚来杯“2022牛客暑期多校训练营5 Don‘t Starve
  7. Vim的插件管理利器pathogen
  8. 设计网站制作步骤是什么?一个好的网站制作标准是怎样的?
  9. rails相当于java中的什么_Rails中的ERB中的%,%=,%#和-%有什么区别?
  10. 图片阴影怎么设置_电影大片风格!教你用PS调出胶片质感的图片