Beautiful Soup 定位指南

Reference: http://blog.csdn.net/abclixu123/article/details/38502993

网页中有用的信息通常存在于网页中的文本或各种不同标签的属性值,为了获得这些网页信息,有必要有一些查找方法可以获取这些文本值或标签属性。而Beautiful Soup中内置了一些查找方式:

  • find()
  • find_all()
  • find_parent()
  • find_parents()
  • find_next_sibling()
  • find_next_siblings()
  • find_previous_sibling()
  • find_previous_siblings()
  • find_previous()
  • find_all_previous()
  • find_next()
  • find_all_next()

使用find()查找

以下这段HTML是例程要用到的参考网页

[html] view plain copy

print?

  1. <html>
  2. <body>
  3. <div class="ecopyramid">
  4. <ul id="producers">
  5. <li class="producerlist">
  6. <div class="name">plants</div>
  7. <div class="number">100000</div>
  8. </li>
  9. <li class="producerlist">
  10. <div class="name">algae</div>
  11. <div class="number">100000</div>
  12. </li>
  13. </ul>
  14. <ul id="primaryconsumers">
  15. <li class="primaryconsumerlist">
  16. <div class="name">deer</div>
  17. <div class="number">1000</div>
  18. </li>
  19. <li class="primaryconsumerlist">
  20. <div class="name">rabbit</div>
  21. <div class="number">2000</div>
  22. </li>
  23. <ul>
  24. <ul id="secondaryconsumers">
  25. <li class="secondaryconsumerlist">
  26. <div class="name">fox</div>
  27. <div class="number">100</div>
  28. </li>
  29. <li class="secondaryconsumerlist">
  30. <div class="name">bear</div>
  31. <div class="number">100</div>
  32. </li>
  33. </ul>
  34. <ul id="tertiaryconsumers">
  35. <li class="tertiaryconsumerlist">
  36. <div class="name">lion</div>
  37. <div class="number">80</div>
  38. </li>
  39. <li class="tertiaryconsumerlist">
  40. <div class="name">tiger</div>
  41. <div class="number">50</div>
  42. </li>
  43. </ul>
  44. </body>
  45. </html>

以上代码是一个生态金字塔的简单展示,为了找到其中的第一生产者,第一消费者或第二消费者,我们可以使用Beautiful Soup的查找方法。一般来说,为了找到BeautifulSoup对象内任何第一个标签入口,我们可以使用find()方法。

找到第一生产者

可以明显看到,生产者在第一个<ul>标签里,因为生产者是在整个HTML文档中第一个<ul>标签中出现,所以可以简单的使用find()方法找到第一生产者。下图HTML树代表了第一个生产者所在位置。

然后在ecologicalpyramid.py中写入下面一段代码,使用ecologicalpyramid.html文件创建BeautifulSoup对象。

[python] view plain copy

print?

  1. from bs4 import BeautifulSoup
  2. with open("ecologicalpyramid.html","r") as ecological_pyramid:
  3. soup = BeautifulSoup(ecological_pyramid)
  4. producer_entries = soup.find("ul")
  5. print(producer_entries.li.div.string)

输出得到:plants

find()说明

find()函数如下:

find(name,attrs,recursive,text,**wargs)

这些参数相当于过滤器一样可以进行筛选处理。

不同的参数过滤可以应用到以下情况:

  • 查找标签,基于name参数
  • 查找文本,基于text参数
  • 基于正则表达式的查找
  • 查找标签的属性,基于attrs参数
  • 基于函数的查找

 通过标签查找

我们可以传递任何标签的名字来查找到它第一次出现的地方。找到后,find函数返回一个BeautifulSoup的标签对象。

[python] view plain copy

print?

  1. from bs4 import BeautifulSoup
  2. with open("ecologicalpyramid.html", "r") as ecological_pyramid:
  3. soup = BeautifulSoup(ecological_pyramid,"html")
  4. producer_entries = soup.find("ul")
  5. print(type(producer_entries))

输出的得到 <class ‘bs4.element.Tag‘>

通过文本查找

直接字符串的话,查找的是标签。如果想要查找文本的话,则需要用到text参数。如下所示:

[html] view plain copy

print?

  1. from bs4 import BeautifulSoup
  2. with open("ecologicalpyramid.html", "r") as ecological_pyramid:
  3. soup = BeautifulSoup(ecological_pyramid,"html")
  4. plants_string = soup.find(text="plants")
  5. print(plants_string)

输出:plants

通过正则表达式查找

有以下HTML代码:

[html] view plain copy

print?

  1. <br/>
  2. <div>The below HTML has the information that has email ids.</div>
  3. [email protected]
  4. <div>[email protected]</div>
  5. <span>[email protected]</span>

如果想找出第一个邮箱地址,但是由于第一个邮箱地址没有标签包含,所以通过其他方式很难找到。但是我们可以把邮箱地址进行正则表达式处理,这样就容易多了。

参考如下代码:

[python] view plain copy

print?

  1. import re
  2. from bs4 import BeautifulSoup
  3. email_id_example = """<br/>
  4. <div>The below HTML has the information that has email ids.</div>
  5. [email protected]
  6. <div>[email protected]</div>
  7. <span>[email protected]</span>
  8. """
  9. soup = BeautifulSoup(email_id_example)
  10. emailid_regexp = re.compile("\[email protected]\w+\.\w+")
  11. first_email_id = soup.find(text=emailid_regexp)
  12. print(first_email_id)

输出:[email protected]

通过标签属性进行查找

观看例程HTML代码,其中第一消费者在ul标签里面且id属性为priaryconsumers.

因为第一消费者出现的ul不是文档中第一个ul,所以通过前面查找标签的办法就行不通了。现在通过标签属性进行查找,参考代码如下:

[python] view plain copy

print?

  1. from bs4 import BeautifulSoup
  2. with open("ecologicalpyramid.html", "r") as ecological_pyramid:
  3. soup = BeautifulSoup(ecological_pyramid,"html")
  4. primary_consumer = soup.find(id="primaryconsumers")
  5. print(primary_consumer.li.div.string)

输出:deer

通过标签属性查找的方式适用于大多数标签属性,包括id,style,title,但是有一组标签属性例外。

  • Custom attrbutes
  • Class

此时,我们需要借助attrs参数来进行传递。

基于定制属性的查找

比如我们HTML5标签中的data-custom属性,如果我们这样

[python] view plain copy

print?

  1. customattr = ""‘<p data-custom="custom">custom attribute
  2. example</p>"""
  3. customsoup = BeautifulSoup(customattr,‘lxml‘)
  4. customSoup.find(data-custom="custom")

那么则会报错。原因是在Python中变量不能呢含有-这个字符,而我们传递的data-custom有-这个字符。

解决的办法是在attrs属性用字典进行传递参数。

[python] view plain copy

print?

  1. using_attrs = customsoup.find(attrs={‘data-custom‘:‘custom‘})
  2. print(using_attrs)

基于CSS类的查找

 

因为class是Python的保留关键字,所以无法使用class这个关键字。所以解决办法类似上面。

[python] view plain copy

print?

  1. css_class = soup.find(attrs={‘class‘:‘primaryconsumerlist‘})
  2. print(css_class)

还有另一个办法。BeautifulSoup有一个特别的关键字参数class_。示例:

方法1:

[python] view plain copy

print?

  1. css_class = soup.find(class_ = "primaryconsumers" )

方法2:

[python] view plain copy

print?

  1. css_class = soup.find(attrs={‘class‘:‘primaryconsumers‘})

基于定义的函数进行查找

可以传递函数到find()来基于函数定义的条件进行查找。函数值必须返回true或者false。

例子:

[python] view plain copy

print?

  1. def is_secondary_consumers(tag):
  2. return tag.has_attr(‘id‘) and tag.get(‘id‘) ==
  3. ‘secondaryconsumers‘

[python] view plain copy

print?

  1. secondary_consumer = soup.find(is_secondary_consumers)
  2. print(secondary_consumer.li.div.string)

输出:fox

把方法进行组合后进行查找

 

可以用其中任何方法进行组合来进行查找,比如同时基于标签名和id号。

使用find_all查找

find()用来查找第一个匹配结果出现的地方,而find_all()正如名字所示,将会找到所有匹配结果出现的地方。应用到find()中的不同过滤参数同理可以用到find_all()中,实际上,过滤参数可以用于任何查找函数,如find_parents()或和find_siblings()。

查找所有三级消费者

[python] view plain copy

print?

  1. all_tertiaryconsumers =
  2. soup.find_all(class_="tertiaryconsumerslist")

其all_tertiaryconsumers的类型是列表。

所以我们对其列表进行迭代,循环输出三级消费者的名字。

[python] view plain copy

print?

  1. for tertiaryconsumer in all_tertiaryconsumers:
  2. print(tertiaryconsumer.div.string)

输出:

lion

tiger

理解用于find_all()的参数

 

相比find(),find_all()有个额外的参数limit,如下所示:

find_all(name,attrs,recursive,text,limit,**kwargs)

limit参数可以限制我们想要得到结果的数目。参照前面的邮件地址例子,我们可以得到所有右键地址通过:

[python] view plain copy

print?

  1. email_ids = soup.find_all(text=emailid_regexp)
  2. print(email_ids)

输出:[u‘[email protected]‘,u‘[email protected]‘,u‘[email protected]‘]

当我们使用limit参数,效果如下:

[python] view plain copy

print?

  1. email_ids_limited = soup.find_all(text=emailid_regexp,limit=2)
  2. print(email_ids_limited)

限制得到两个结果,所以输出为:

[u‘[email protected]‘,u‘[email protected]‘]

说白了,find()也就是当limit=1时的find_all()。

可以向find函数传递True或False参数,如果我们传递True给find_all(),则返回所有soup对象的标签。对于find()来说,则返回第一个标签。

举例查找文本,传递True将会返回所有文本。

[python] view plain copy

print?

  1. all_texts = soup.find_all(text=True)
  2. print(all_texts)

输出:

[u‘\n‘, u‘\n‘, u‘\n‘, u‘\n‘, u‘\n‘, u‘plants‘, u‘\n‘, u‘100000‘, 
u‘\n‘, u‘\n‘, u‘\n‘, u‘algae‘, u‘\n‘, u‘100000‘, u‘\n‘, u‘\n‘, 
u‘\n‘, u‘\n‘, u‘\n‘, u‘deer‘, u‘\n‘, u‘1000‘, u‘\n‘, u‘\n‘, 
u‘\n‘, u‘rabbit‘, u‘\n‘, u‘2000‘, u‘\n‘, u‘\n‘, u‘\n‘, 
u‘\n‘, u‘\n‘, u‘fox‘, u‘\n‘, u‘100‘, u‘\n‘, u‘\n‘, u‘\n‘, 
u‘bear‘, u‘\n‘, u‘100‘, u‘\n‘, u‘\n‘, u‘\n‘, u‘\n‘, 
u‘\n‘, u‘lion‘, u‘\n‘, u‘80‘, u‘\n‘, u‘\n‘, u‘\n‘, 
u‘tiger‘, u‘\n‘, u‘50‘, u‘\n‘, u‘\n‘, u‘\n‘, u‘\n‘, 
u‘\n‘]

同样的,我们可以在传递text参数时传递一个字符串列表,那么find_all()会找到诶个在列表中定义过的字符串。

[python] view plain copy

print?

  1. all_texts_in_list = soup.find_all(text=["plants","algae"])
  2. print(all_texts_in_list)

输出:

[python] view plain copy

print?

  1. [u‘plants‘, u‘algae‘]

这个同样适用于查找标签,标签属性,定制属性和CSS类。如:

[python] view plain copy

print?

  1. div_li_tags = soup.find_all(["div","li"])

find()和find_all()都会查找一个对象所有后辈们,不过我们可以控制它通过recursive参数。如果recursive=False,那么超找只会找到该对象的最近后代。

通过标签之间的关系进行查找

我们可以通过find()和find_all()来查找到想要内容。但有时候,我们需要查看的与之内容相关先前的标签或者后面的标签来获取额外的信息。比如方法find_parents()和find_next_siblings()等等。一般的,在find()和find_all()方法后使用上述方法,因为find()和find_all()可以找到特殊的一个标签,然后我们可以通过这个特殊的标签找到其他的想要的与之有关系的标签。

查找父标签

通过find_parents()或find_parent()。它们之间的不同就类似于find()和find_all()的区别。find_parents()返回全部的相匹配的父标签,而find_paret()返回最近的一个父标签。适用于find()的方法同样也使用于这两个方法。

在前面的第一消费者例子中,我们可以找到离Primaryconsumer最近的ul父标签。

[python] view plain copy

print?

  1. primaryconsumers = soup.find_all(class_="primaryconsumerlist")
  2. primaryconsumer = primaryconsumers[0]
  3. parent_ul = primaryconsumer.find_parents(‘ul‘)
  4. print(parent_ul)

一个简单的找到一个标签的父标签的方法就是使用find_parent()却不带任何参数。

[python] view plain copy

print?

  1. immediateprimary_consumer_parent = primary_consumer.find_parent()

查找同胞

如果标签在同一个等级的话,我们可以说这些标签是同胞的关系,比如参照上面金字塔例子,所有ul标签就是同胞的关系。

上图ul标签下的producers,primaryconsumers,secondaryconsumers,teriaryconsumers就是同胞关系。

再看下面这个图:

div下的plants和algae不是同胞关系,但是plants和临近的number是同胞关系。

Beautiful Soup自带有查找同胞的方法。

比如find_next_siblings()和find_next_sibling()查找对象下面的同胞。举例:

[python] view plain copy

print?

  1. producers= soup.find(id=‘producers‘)
  2. next_siblings = producers.find_next_siblings()
  3. print(next_siblings)

将会输出与之临近的下面的所有同胞HTML代码。

查找下一个

对每一个标签来说,下一个元素可能会是定位字符串,标签对象或者其他BeautifulSoup对象。我们定义下一个元素为与当前元素最靠近的元素。这个不同于同胞定义。我们有方法可以找到我们想要标签的下一个其他元素对象。find_all_next()找到与当前元素靠近的所有对象。而find_next()找到离当前元素最接近的对象。

比如,找到在第一个div标签后的所有li标签

[python] view plain copy

print?

  1. first_div = soup.div
  2. all_li_tags = first_div.find_all_next("li")

输出“:

[<li class="producerlist">
<div class="name">plants</div>
<div class="number">100000</div>
</li>, <li class="producerlist">
<div class="name">algae</div>
<div class="number">100000</div>
</li>, <li class="primaryconsumerlist">
<div class="name">deer</div>
<div class="number">1000</div>
</li>, <li class="primaryconsumerlist">
<div class="name">rabbit</div>
<div class="number">2000</div>
</li>, <li class="secondaryconsumerlist">
<div class="name">fox</div>
<div class="number">100</div>
</li>, <li class="secondaryconsumerlist">
<div class="name">bear</div>
<div class="number">100</div>
</li>, <li class="tertiaryconsumerlist">
<div class="name">lion</div>
<div class="number">80</div>
</li>, <li class="tertiaryconsumerlist">
<div class="name">tiger</div>
<div class="number">50</div>
</li>]

时间: 2024-07-30 15:56:32

Beautiful Soup 定位指南的相关文章

2017.08.11 Python网络爬虫实战之Beautiful Soup爬虫

1.与Scrapy不同的是Beautiful Soup并不是一个框架,而是一个模块:与Scrapy相比,bs4中间多了一道解析的过程(Scrapy是URL返回什么数据,程序就接受什么数据进行过滤),bs4则在接收数据和进行过滤之间多了一个解析的过程,根据解析器的不同,最终处理的数据也有所不同,加上这一步骤的优点是可以根据输入数据的不同进行针对性的解析:同一选择lxml解析器: 2.安装Beautiful Soup环境:pip install beautifulsoup4 3.Beautiful

详解Python 采用 requests + Beautiful Soup 爬取房天下新楼盘推荐

最近一直在关注Python写爬虫相关的知识,尝试了采用requests + Beautiful Soup来爬取房天下(原搜房网)的推荐新楼盘. 不用不知道,一用发现有惊喜也有惊吓,本文就一同记录下惊喜和踩的一些乱码的坑. 首先,觉得Beautiful soup解析网页更加符合人类的常规思维,比使用正则表达式(python中的re库)更容易理解. 同时关于requests遇到了中文字符和特殊字符解码的问题.本文都将给于深入的解说. 软件环境 Python    : 3.6.0 PyCharm: C

第四部分 解析库的使用(XPath、Beautiful Soup、PyQuery)

在网页节点中,可以定义id.class或其他属性.节点间有层次关系,网页中要通过XPath或CSS选择器定位一个或多个节点.在页面解析时,可利用XPath或CSS选择器提取某个节点,再调用相应方法获取它的正文内容或者属性,就可提取到想要的信息.在python中常用的解析库有lxml.Beautiful Soup.pyquery等.使用这些库可以很大程度上提高效率. 一 使用XPath解析库 XPath,全称XML Path Language,即XML路径语言,是一门在XML文档中查找信息的语言.

爬虫---Beautiful Soup 爬取图片

上一篇简单的介绍Beautiful Soup 的基本用法,这一篇写下如何爬取网站上的图片,并保存下来 爬取图片 1.找到一个福利网站:http://www.xiaohuar.com/list-1-1.html 2.通过F12进行定位图片 3.通过下图可以看到标签为img,然后通过width="210"的属性 爬取方法 1.通过find_all()的方法进行查找图片位置 2.筛选出图片的URL和图片名称 3.筛选后会发现其中有一些图片URL不完整 4.这个时候需要在代码中加一个判断,如何

[Python]HTML/XML解析器Beautiful Soup

[简介] Beautiful Soup是一个可以从HTML或XML文件中提取数据的Python库.即HTML/XMLX的解析器. 它可以很好的处理不规范标记并生成剖析树(parse tree). 它提供简单又常用的导航(navigating),搜索以及修改剖析树的操作.它可以大大节省你的编程时间. [安装] 下载地址:点击打开链接 Linux平台安装: 如果你用的是新版的Debain或ubuntu,那么可以通过系统的软件包管理来安装: $ apt-get install Python-bs4 B

python标准库Beautiful Soup与MongoDb爬喜马拉雅电台的总结

Beautiful Soup标准库是一个可以从HTML/XML文件中提取数据的Python库,它能够通过你喜欢的转换器实现惯用的文档导航,查找,修改文档的方式,Beautiful Soup将会节省数小时的工作时间.pymongo标准库是MongoDb NoSql数据库与python语言之间的桥梁,通过pymongo将数据保存到MongoDb中.结合使用这两者来爬去喜马拉雅电台的数据... Beautiful Soup支持Python标准库中的HTML解析器,还支持一些第三方的解析器,其中一个是

HDU 4782 Beautiful Soup(模拟)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4782 Problem Description Coach Pang has a lot of hobbies. One of them is playing with "tag soup" with the help of Beautiful Soup. Coach Pang is satisfied with Beautiful Soup in every respect, except

爬虫学习——网页解析器Beautiful Soup

一.Beautiful Soup的安装与测试 官方网站:https://www.crummy.com/software/BeautifulSoup/ Beautiful Soup安装与使用文档:  https://www.crummy.com/software/BeautifulSoup/bs4/doc/ 1.首先测试一下bs4模块是否已经存在,若不存在再安装即可,我用的是kali测试发现bs4模块已经存在,下面介绍如何测试与安装 新建python文档输入以下代码 1 import bs4 2

Beautiful Soup的使用

Beautiful Soup简单实用,功能也算比较全,之前下载都是自己使用xpath去获取信息,以后简单的解析可以用这个,方便省事. Beautiful Soup 是用 Python 写的一个 HTML/XML 的解析器,它可以很好的处理不规范标记并生成剖析树.通常用来分析爬虫抓取的web文档.对于 不规则的 Html文档,也有很多的补全功能,节省了开发者的时间和精力. Beautiful Soup 的官方文档齐全,将官方给出的例子实践一遍就能掌握.官方英文文档,中文文档 一 安装 Beauti