【问题标题】:How to apply multiple arguments within find_all function?如何在 find_all 函数中应用多个参数?
【发布时间】:2017-11-16 18:03:09
【问题描述】:

是否可以在单个soup.find_all 函数中使用多个参数来从某些元素中查找任何特定项目?如果我选择soup.select 选项,我想知道的过程可以很容易地应用。更具体地说:看下面的例子:

from bs4 import BeautifulSoup

html_element='''
<div class="browse-movie-bottom">
    <a href="https://yts.ag/movie/logan-lucky-2017" class="browse-movie-title">Logan Lucky</a>
    <div class="browse-movie-year">2017</div>
    <div class="browse-movie-tags">
        <a href="https://yts.ag/torrent/download" rel="nofollow" title="Logan Lucky">Logan Lucky 720p</a>
        <a href="https://yts.ag/torrent/download" rel="nofollow" title="Logan Lucky">Logan Lucky 1080p</a>
    </div>
</div>
'''
soup = BeautifulSoup(html_element,"lxml")
for item in soup.find_all(class_='browse-movie-bottom')[0].find_all(class_='browse-movie-tags')[0].find_all("a"):
# for item in soup.select(".browse-movie-bottom .browse-movie-tags a"):
    print(item.text)

一方面,我使用soup.select() 解析电影标签,您知道可以这样使用它,以便所有参数可以放在一个大括号中。

另一方面,我使用soup.find_all() 做了同样的事情,它需要三个不同的大括号中的三个不同的参数。结果是一样的。

我的问题是:是否可以使用 soup.find_all() 函数创建任何表达式,该函数将在单个大括号中包含多个参数,就像我对 soup.select() 所做的那样。如下所示:

这是一个错误的,但它会让你知道我在追求什么类型的表达:

soup.find_all({'class':'browse-movie-bottom'},{'class':'browse-movie-tags'},"a")[0]

但是,有效的搜索结果是:

Logan Lucky 720p
Logan Lucky 1080p

【问题讨论】:

  • 这种情况下select的缺点是什么?
  • 所以,只有当我在 soup.select 函数中遇到任何缺点时,我才应该使用 find_all 函数,这就是你的意思 @PRMoureu 吗?我想学习它。就是这样。

标签: python python-3.x web-scraping beautifulsoup


【解决方案1】:

您可以将一个列表传递给class_ 属性,这样您就可以将一个调用保存到find_all,但是您需要使用"a" 再次调用它,并且您始终可以使用快捷方式调用soup("a")find_all

from bs4 import BeautifulSoup
html_element='''
<div class="browse-movie-bottom">
    <a href="https://yts.ag/movie/logan-lucky-2017" class="browse-movie-title">Logan Lucky</a>
    <div class="browse-movie-year">2017</div>
    <div class="browse-movie-tags">
        <a href="https://yts.ag/torrent/download" rel="nofollow" title="Logan Lucky">Logan Lucky 720p</a>
        <a href="https://yts.ag/torrent/download" rel="nofollow" title="Logan Lucky">Logan Lucky 1080p</a>
    </div>
</div>
'''
soup = BeautifulSoup(html_element,"lxml")
for item in soup.findAll(class_=['browse-movie-bottom', 'browse-movie-tags'])[1]('a'):
#for item in soup.select(".browse-movie-bottom .browse-movie-tags a"):
    print(item.text)

【讨论】:

  • 感谢拉玛,您的回答。它非常接近我的预期。
  • 只有一件事:为什么索引变成[1]
【解决方案2】:

您应该使用 CSS 选择器:

>>> soup.select(".browse-movie-bottom .browse-movie-tags a")
[<a href="https://yts.ag/torrent/download" rel="nofollow" title="Logan Lucky">Logan Lucky 720p</a>, <a href="https://yts.ag/torrent/download" rel="nofollow" title="Logan Lucky">Logan Lucky 1080p</a>]
>>> [item.text for item in soup.select(".browse-movie-bottom .browse-movie-tags a")]
[u'Logan Lucky 720p', u'Logan Lucky 1080p']

更多信息:https://www.crummy.com/software/BeautifulSoup/bs4/doc/#css-selectors

除非你不能用 CSS 选择器做一些事情(因为不是所有的都实现了),你应该使用select。否则,使用更繁琐的find_all

未实现的 CSS 选择器示例:第 n 个子项。 selecting second child in beautiful soup with soup.select?

【讨论】:

  • @Samuel GIFFARD,你在这里展示的东西我已经在那里做了。我想知道如何对 find_all 函数做同样的事情。您可能忘记阅读说明。还是谢谢。
  • 刚刚对其进行了编辑,以便为您(或将来可能想知道与您相同的事情的任何人)提供更多信息:-)
  • @Topto 如果您觉得这个答案可以帮助您或将来的任何人。请验证并投票。如果不满意,请说一下哪方面不满意,以便改进。
  • 我再次提醒你这个问题的标题。我只寻找与 find_all 函数而不是选择器相关的任何答案。谢谢。
猜你喜欢
  • 2012-01-05
  • 1970-01-01
  • 1970-01-01
  • 2016-01-17
  • 2018-09-25
  • 1970-01-01
  • 1970-01-01
  • 2022-01-27
  • 2013-07-15
相关资源
最近更新 更多