Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 4 additions & 6 deletions scrapling/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -300,7 +300,9 @@ def get_all_text(

ignored_elements: set[Any] = set()
if ignore_tags:
ignored_elements.update(self._root.iter(*ignore_tags))
for element in self._root.iter(*ignore_tags):
if element not in ignored_elements:
ignored_elements.update(element.iter())

_all_strings = []

Expand All @@ -315,11 +317,7 @@ def is_visible_text_node(text_node: _ElementUnicodeResult) -> bool:
return False

owner = parent.getparent() if text_node.is_tail else parent
while owner is not None:
if owner in ignored_elements:
return False
owner = owner.getparent()
return True
return owner not in ignored_elements

for text_node in cast(list[_ElementUnicodeResult], _find_all_text_nodes(self._root)):
text = str(text_node)
Expand Down
17 changes: 17 additions & 0 deletions tests/parser/test_parser_advanced.py
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,23 @@ def test_get_all_text_preserves_interleaved_text_nodes(self):

assert node.get_all_text("\n", strip=True) == "string1\nstring2\nstring3\nstring4\nstring5\nstring6\nstring7"

def test_get_all_text_keeps_text_after_comment(self):
"""Tail text following a comment or PI node must still be collected"""
html = "<div>before<!-- c -->after<p>x</p></div>"
assert Selector(html, keep_comments=True).get_all_text() == "before\nafter\nx"

def test_get_all_text_deep_nesting(self):
"""Deeply nested trees collect every visible text node and skip ignored subtrees"""
depth = 500
html = "<div>" + "".join(f"<span>t{i}" for i in range(depth)) + "leaf" + "</span>" * depth + "end</div>"
text = Selector(html).get_all_text(strip=True)
assert text.startswith("t0\nt1\n")
assert "leaf" in text and text.endswith("end")
assert text.count("\n") == depth

ignored = "<div>keep<script>" + "<b>x</b>" * depth + "</script>done</div>"
assert Selector(ignored).get_all_text(strip=True) == "keep\ndone"


class TestTextHandlerAdvanced:
"""Test advanced TextHandler functionality"""
Expand Down