2 HTML分解(2)

findAll 函数负责发现基于名字和属性的标签。然而,如果你需要发现一个文档中基于位置的标签,该如何做呢?那就是 Navigating Trees (NT)出现的原因。在第一章中,我们看到了以一个单方向的导航的BS树:

bsObj.tag.subTag.anotherSubTag

现在让我们看看下面的例子, http://www.pythonscraping.com/pages/page3.html

这里写图片描述

该网页以一种树形结构组织:

htmlbodydiv.wrapperh1div.contenttable#giftListtrththththtr.gift#gift1tdtdspan.excitingNotetdtdimg...table rows continuediv.footer

在下面的某些部分,我们也会使用一个相同的HTML结构作为一个例子。

处理子女(children)和后代(descendants)

  • 子女:是最接近父辈下面的一个标签
  • 后代:是父辈下面的任意一层
    比如说:trtable 的子女,而 tr, th, td, img, spantag 的后代。因此,子女都是后代,但后代并不一定是子女。

通常而言,BS函数一直处理当前标签的后代。比如:bsObj.body.h1

相似的,bsObj.div.findAll("img") 会发现文档下面的第一个div 标签,然后检索 img标签。

如果你仅仅想那些是子女的后代,你可以使用.children 标签:

from url lib.request import url open
from bs4 import BeautifulSoup

html = urlopen("http://www.pythonscraping.com/pages/page3.html")
bsObj = BeautifulSoup(html)
for child in bsObj.find("table",{"id":"giftList"}).children:
    print(child)

输出结果为:
这里写图片描述

这段代码会输出giftList 表格下的产品行。如果使用descenants ,则大约二十打的标签会输出,包括了img, span, td 标签。输出结果为:
这里写图片描述

这就是子女与后代之间的区别。

处理兄弟姐妹

BS中next_siblings 函数使得可以从表格中更好的收集数据,特别是标题行:

from urllib.request import urlopen
from urllib.error import HTTPError, URLError
from bs4 import BeautifulSoup

html = urlopen("http://www.pythonscraping.com/pages/page3.html")
bsObj = BeautifulSoup(html)
for sibling in bsObj.find("table",{"id":"giftList"}).tr.next_siblings:
        print(sibling)

结果为:
这里写图片描述

从结果可知,这段代码输出了所有产品行,除了表格的的第一行。为什么第一行跳过了呢?两个原因:(1)对象不能是它自己的兄弟姐妹,因此,对象不会包含在这个列表中;(2)这个函数仅仅调用了下一个兄弟姐妹。如果我们去选择列表中间的一个行,可以调用next_siblings,然后仅仅下一个兄弟姐妹会被返回。所以,选择title 行,然后调用next_siblings ,我们可以选择所在的列表,除了标题行。

做特殊的选择
如果我们选择bsObj.table.tr 甚至仅仅是bsObj.tr,其结果就是列表的第一行。然而,我还是选择了一个长的代码:
bsObj.find("table",{"id":"giftList"}).tr
尽管它看上去仅有一个表格,它很容易失去一些东西。除此之外,网页的布局会随时发生变化。在网页中的第一个标签的样子很有可能在后来变成网页中的第二个标签,或者第三个标签。为了使你的爬虫更加的健壮,最好的方式是做标签选择的时候,尽可能的特别。所以要充分利用标签属性。

作为next_siblings 的补充,previous_siblings 函数也是很有帮助的,如果很容易的选择出兄弟姐妹的标签的末尾。

当然,也有next_siblingprevious_sibling 函数,仅仅返回列表中的单个标签。

处理父辈

当爬虫网页的时候,你会发现你需要发现标签父辈的次数少于需要发现子女或者兄弟姐妹。发现BS父辈的函数,.parent.parents 。比如:

from urllib.request import urlopen
from urllib.error import HTTPError, URLError
from bs4 import BeautifulSoup

html = urlopen("http://www.pythonscraping.com/pages/page3.html")
bsObj = BeautifulSoup(html)
print(bsObj.find("omg",{"src":"../img/gifts/img1.jpg"}).parent.previous_sibling.get_text())

输出结果为:”$15.00”。

为什么结果会是这样呢?下面是树形结构:

trtdtdtd(3)"$15.00"(4)td(2)< img src="../img/gifts/img1.jpg">(1)

  1. 首先选择图像标签;
  2. 选择标签的父辈;
  3. 选择父辈的前一个兄弟姐妹;
  4. 选择标签文本。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值