Beautiful Soup – 搜索树

Beautiful Soup – 搜索树

有许多Beautifulsoup方法,允许我们搜索解析树。两个最常用的方法是 find() 和 find_all()。

在谈论find()和find_all()之前,让我们看看你可以传递给这些方法的不同过滤器的一些例子。

过滤器的种类

我们有不同的过滤器可以传入这些方法,对这些过滤器的理解是至关重要的,因为这些过滤器在整个搜索API中被反复使用。我们可以根据标签的名称、属性、字符串的文本或它们的混合来使用这些过滤器。

一个字符串

最简单的过滤器类型之一是字符串。向搜索方法传递一个字符串,Beautifulsoup将对该确切的字符串进行匹配。

下面的代码将找到文档中所有的

标签 –

>>> markup = BeautifulSoup('<p>Top Three</p><p><pre>Programming Languages are:</pre></p><p><b>Java, Python, Cplusplus</b></p>')
>>> markup.find_all('p')
[<p>Top Three</p>, <p></p>, <p><b>Java, Python, Cplusplus</b></p>]

正则表达式

你可以找到所有以给定字符串/标签开始的标签。在这之前,我们需要导入re模块来使用正则表达式。

>>> import re
>>> markup = BeautifulSoup('<p>Top Three</p><p><pre>Programming Languages are:</pre></p><p><b>Java, Python, Cplusplus</b></p>')
>>>
>>> markup.find_all(re.compile('^p'))
[<p>Top Three</p>, <p></p>, <pre>Programming Languages are:</pre>, <p><b>Java, Python, Cplusplus</b></p>]

列表

你可以通过提供一个列表来传递多个要查找的标签。下面的代码可以找到所有的

<

pre>标签 –

>>> markup.find_all(['pre', 'b'])
[<pre>Programming Languages are:</pre>, <b>Java, Python, Cplusplus</b>]

True

True将返回它能找到的所有标签,但不包括其本身的字符串 —

>>> markup.find_all(True)
[<html><body><p>Top Three</p><p></p><pre>Programming Languages are:</pre>
<p><b>Java, Python, Cplusplus</b> </p> </body></html>, 
<body><p>Top Three</p><p></p><pre> Programming Languages are:</pre><p><b>Java, Python, Cplusplus</b></p>
</body>, 
<p>Top Three</p>, <p></p>, <pre>Programming Languages are:</pre>, <p><b>Java, Python, Cplusplus</b></p>, <b>Java, Python, Cplusplus</b>]

为了只返回上述汤中的标签–

>>> for tag in markup.find_all(True):
(tag.name)
'html'
'body'
'p'
'p'
'pre'
'p'
'b'

find_all()

你可以使用find_all从页面响应中提取一个特定标签的所有出现,如-

语法

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

让我们从IMDB中提取一些有趣的数据–有史以来的 “最高评分电影”。

>>> url="https://www.imdb.com/chart/top/?ref_=nv_mv_250"
>>> content = requests.get(url)
>>> soup = BeautifulSoup(content.text, 'html.parser')
#Extract title Page
>>> print(soup.find('title'))
<title>IMDb Top 250 - IMDb</title>

#Extracting main heading
>>> for heading in soup.find_all('h1'):
   print(heading.text)
Top Rated Movies

#Extracting sub-heading
>>> for heading in soup.find_all('h3'):
   print(heading.text)

IMDb Charts
You Have Seen
   IMDb Charts
   Top India Charts
Top Rated Movies by Genre
Recently Viewed

从上面,我们可以看到find_all会给我们提供所有符合我们定义的搜索条件的项目。所有我们可以在find_all()中使用的过滤器都可以用于find()和其他搜索方法,如find_parents()或find_siblings()。

find()

我们在上面看到,find_all()是用来扫描整个文档以找到所有内容的,但是有些东西,要求只找到一个结果。如果你知道文档只包含一个<body>标签,那么搜索整个文档是浪费时间的。一种方法是每次都调用limit=1的find_all()方法,或者我们可以使用find()方法来做同样的事情。

语法

find(name, attrs, recursive, string, **kwargs)

因此,以下两种不同的方法给出了相同的输出−

>>> soup.find_all('title',limit=1)
[<title>IMDb Top 250 - IMDb</title>]
>>>
>>> soup.find('title')
<title>IMDb Top 250 - IMDb</title>

在上面的输出中,我们可以看到find_all()方法返回一个包含单个项目的列表,而find()方法返回单个结果。

find()和find_all()方法的另一个区别是 —

>>> soup.find_all('h2')
[]
>>>
>>> soup.find('h2')

如果soup.find_all()方法找不到任何东西,它将返回空列表,而find()则返回无。

find_parents() 和 find_parent()

与find_all()和find()方法不同的是,find_parents()和find_parents方法()做的是相反的事情,它们向上遍历树,寻找一个标签(或一个字符串)的父代。

语法

find_parents(name, attrs, string, limit, **kwargs)
find_parent(name, attrs, string, **kwargs)

>>> a_string = soup.find(string="The Godfather")
>>> a_string
'The Godfather'
>>> a_string.find_parents('a')
[<a href="/title/tt0068646/" title="Francis Ford Coppola (dir.), Marlon Brando, Al Pacino">The Godfather</a>]
>>> a_string.find_parent('a')
<a href="/title/tt0068646/" title="Francis Ford Coppola (dir.), Marlon Brando, Al Pacino">The Godfather</a>
>>> a_string.find_parent('tr')
<tr>

<td class="posterColumn">
<span data-value="2" name="rk"></span>
<span data-value="9.149038526210072" name="ir"></span>
<span data-value="6.93792E10" name="us"></span>
<span data-value="1485540" name="nv"></span>
<span data-value="-1.850961473789928" name="ur"></span>
<a href="/title/tt0068646/"> <img alt="The Godfather" height="67" src="https://m.media-amazon.com/images/M/MV5BM2MyNjYxNmUtYTAwNi00MTYxLWJmNWYtYzZlODY3ZTk3OTFlXkEyXkFqcGdeQXVyNzkwMjQ5NzM@._V1_UY67_CR1,0,45,67_AL_.jpg" width="45"/>
</a> </td>
<td class="titleColumn">
2.
<a href="/title/tt0068646/" title="Francis Ford Coppola (dir.), Marlon Brando, Al Pacino">The Godfather</a>
<span class="secondaryInfo">(1972)</span>
</td>
<td class="ratingColumn imdbRating">
<strong title="9.1 based on 1,485,540 user ratings">9.1</strong>
</td>
<td class="ratingColumn">
<div class="seen-widget seen-widget-tt0068646 pending" data-titleid="tt0068646">
<div class="boundary">
<div class="popover">
<span class="delete"> </span><ol><li>1<li>2<li>3<li>4<li>5<li>6<li>7<li>8<li>9<li>10</li>0</li></li></li></li&td</li></li></li></li></li></ol> </div>
</div>
<div class="inline">
<div class="pending"></div>
<div class="unseeable">NOT YET RELEASED</div>
<div class="unseen"> </div>
<div class="rating"></div>
<div class="seen">Seen</div>
</div>
</div>
</td>
<td class="watchlistColumn">

<div class="wlb_ribbon" data-recordmetrics="true" data-tconst="tt0068646"></div>
</td>
</tr>
>>>
>>> a_string.find_parents('td')
[<td class="titleColumn">
2.
<a href="/title/tt0068646/" title="Francis Ford Coppola (dir.), Marlon Brando, Al Pacino">The Godfather</a>
<span class="secondaryInfo">(1972)</span>
</td>]

还有其他八种类似的方法–

find_next_siblings(name, attrs, string, limit, **kwargs)
find_next_sibling(name, attrs, string, **kwargs)

find_previous_siblings(name, attrs, string, limit, **kwargs)
find_previous_sibling(name, attrs, string, **kwargs)

find_all_next(name, attrs, string, limit, **kwargs)
find_next(name, attrs, string, **kwargs)

find_all_previous(name, attrs, string, limit, **kwargs)
find_previous(name, attrs, string, **kwargs)

其中、

find_next_siblings()find_next_sibling( ) 方法将遍历当前元素之后的所有兄弟姐妹。

find_previous_siblings()find_previous_sibling() 方法将遍历当前元素之前的所有兄弟姐妹。

find_all_next()find_next() 方法将遍历当前元素之后的所有标签和字符串。

find_all_previousfind_previous() 方法将遍历当前元素之前的所有标签和字符串。

CSS选择器

BeautifulSoup库支持最常用的CSS选择器。你可以在select()方法的帮助下使用CSS选择器来搜索元素。

这里有一些例子–

>>> soup.select('title')
[<title>IMDb Top 250 - IMDb</title>, <title>IMDb Top Rated Movies</title>]
>>>
>>> soup.select("p:nth-of-type(1)")
[<p>The Top Rated Movie list only includes theatrical features.</p>, <p> class="imdb-footer__copyright _2-iNNCFskmr4l2OFN2DRsf">© 1990-2019 by IMDb.com, Inc.</p>]
>>> len(soup.select("p:nth-of-type(1)"))
2
>>> len(soup.select("a"))
609
>>> len(soup.select("p"))
2

>>> soup.select("html head title")
[<title>IMDb Top 250 - IMDb</title>, <title>IMDb Top Rated Movies</title>]
>>> soup.select("head > title")
[<title>IMDb Top 250 - IMDb</title>]

#print HTML code of the tenth li elemnet
>>> soup.select("li:nth-of-type(10)")
[<li class="subnav_item_main">
<a href="/search/title?genres=film_noir&sort=user_rating,desc&title_type=feature&num_votes=25000,">Film-Noir
</a> </li>]

Python教程

Java教程

Web教程

数据库教程

图形图像教程

大数据教程

开发工具教程

计算机教程