【问题标题】:Bs4 select_one vs findBs4 select_one vs find
【发布时间】:2016-08-19 07:40:56
【问题描述】:

我想知道执行bs.find('div')bs.select_one('div') 有什么区别。 find_allselect 也是如此。

在性能方面是否有任何差异,或者在特定情况下是否比其他更好。

【问题讨论】:

    标签: python beautifulsoup html-parsing bs4


    【解决方案1】:

    select()select_one() 使用CSS selectors 为您提供了一种在HTML 树中导航的不同方式,该CSS selectors 具有丰富且方便的语法。虽然,BeautifulSoup 中的 CSS 选择器语法支持是有限,但涵盖了最常见的情况。

    在性能方面,它确实取决于要解析的 HTML 树以及要解析的元素、它的深度以及用于定位它的选择器。另外,将find()select() 进行比较的find() + find_all() 替代方案也很重要。在像bs.find('div')bs.select_one('div') 这样的简单案例中,我想说的是,一般来说,find() 应该执行得更快,因为there is a lot going on to support CSS selector syntax under-the-hood

    【讨论】:

      【解决方案2】:

      select_one 通常比 find 快得多:

      In [13]: req = requests.get("https://httpbin.org/")
      
      In [14]: soup = BeautifulSoup(req.content, "html.parser")
      
      In [15]:  soup.select_one("#DESCRIPTION")
      Out[15]: <h2 id="DESCRIPTION">DESCRIPTION</h2>
      
      In [16]:  soup.find("h2", id="DESCRIPTION")
      Out[16]: <h2 id="DESCRIPTION">DESCRIPTION</h2>
      
      In [17]: timeit  soup.find("h2", id="DESCRIPTION")
      100 loops, best of 3: 5.27 ms per loop
      
      In [18]: timeit  soup.select_one("#DESCRIPTION")
      1000 loops, best of 3: 649 µs per loop
      
      In [19]: timeit  soup.select_one("div")
      10000 loops, best of 3: 61 µs per loop
      In [20]: timeit  soup.find("div")
      1000 loops, best of 3: 446 µs per loop
      

      find 基本上和使用 find_all 设置限制为 1 一样,然后检查返回的列表是否为空,索引,如果不为空如果是,则返回 None。

      def find(self, name=None, attrs={}, recursive=True, text=None,
               **kwargs):
          """Return only the first child of this Tag matching the given
          criteria."""
          r = None
          l = self.find_all(name, attrs, recursive, text, 1, **kwargs)
          if l:
              r = l[0]
          return r
      

      select_one 使用 select 做了类似的事情:

      def select_one(self, selector):
              """Perform a CSS selection operation on the current element."""
              value = self.select(selector, limit=1)
              if value:
                  return value[0]
              return None
      

      在不处理所有关键字参数的情况下,选择的成本要低得多。

      Beautifulsoup : Is there a difference between .find() and .select() - python 3.xx 详细介绍了差异。

      【讨论】:

      • 因为这是谷歌的顶级搜索结果之一:无法确认selectfind_all 在我使用lxml 解析器搜索所有
      • 元素的实时站点上的结果具体类。使用 timeit 运行 1000 次,find_all 比 select (1s) 稍快。
      猜你喜欢
      相关资源
      最近更新 更多
      热门标签