2016-08-19 4 views
2

Мне было интересно, в чем разница между выполнением bs.find('div') и bs.select_one('div'). То же самое касается find_all и select.Bs4 select_one vs find

Есть ли какая-либо разница в производительности, или если в некоторых случаях лучше использовать другую.

ответ

2

select() и select_one() дают вам другой способ навигации по дереву HTML с использованием CSS selectors, который имеет богатый и удобный синтаксис. Хотя поддержка синтаксиса селектора CSS в BeautifulSoup равна , ограничена, но охватывает наиболее распространенные случаи.

Оценка эффективности, это действительно зависит от дерева HTML для синтаксического анализа и от того, какой элемент, насколько он глубокий и какой селектор используется для его поиска. Плюс, то, что find() + find_all() Альтернатива есть, чтобы сравнить select() с, также важно. В простом случае, как bs.find('div') против bs.select_one('div'), я бы сказал, что, как правило, find() должен выполнять быстрее просто потому, что there is a lot going on to support CSS selector syntax under-the-hood.

1

select_one обычно намного быстрее, чем найти:

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_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 делает что-то подобное с помощью выберите:

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 охватывает немного больше различий.

Смежные вопросы