diff options
-rw-r--r-- | bs4/element.py | 11 | ||||
-rw-r--r-- | bs4/tests/test_tree.py | 3 |
2 files changed, 11 insertions, 3 deletions
diff --git a/bs4/element.py b/bs4/element.py index 21e040a..1f121f4 100644 --- a/bs4/element.py +++ b/bs4/element.py @@ -1222,9 +1222,9 @@ class Tag(PageElement): elif '#' in token: # ID selector - tag_name, id = token.split('#', 1) + tag_name, tag_id = token.split('#', 1) def id_matches(tag): - return tag.get('id', None) == id + return tag.get('id', None) == tag_id checker = id_matches elif '.' in token: @@ -1349,6 +1349,7 @@ class Tag(PageElement): _use_candidate_generator = _candidate_generator new_context = [] + new_context_ids = set([]) for tag in current_context: if self._select_debug: print " Running candidate generator on %s %s" % ( @@ -1368,7 +1369,11 @@ class Tag(PageElement): if checker is None or result: if self._select_debug: print " SUCCESS %s %s" % (candidate.name, repr(candidate.attrs)) - new_context.append(candidate) + if id(candidate) not in new_context_ids: + # If a tag matches a selector more than once, + # don't include it in the context more than once. + new_context.append(candidate) + new_context_ids.add(id(candidate)) elif self._select_debug: print " FAILURE %s %s" % (candidate.name, repr(candidate.attrs)) diff --git a/bs4/tests/test_tree.py b/bs4/tests/test_tree.py index 77d4199..b07de8c 100644 --- a/bs4/tests/test_tree.py +++ b/bs4/tests/test_tree.py @@ -1802,3 +1802,6 @@ class TestSoupSelector(TreeTest): def test_dangling_combinator(self): self.assertRaises(ValueError, self.soup.select, 'h1 >') + + def test_sibling_combinator_wont_select_same_tag_twice(self): + self.assertSelects('p[lang] ~ p', ['lang-en-gb', 'lang-en-us', 'lang-fr']) |