From 124b5c2161bd9d13211d7c6f35d616bc444bf8f7 Mon Sep 17 00:00:00 2001 From: ZaynQuinn <95160622+ZaynQuinn@users.noreply.github.com> Date: Fri, 6 Nov 2026 14:54:19 +0800 Subject: [PATCH] fix: avoid selecting feedback form text as article content --- readability/readability.py | 11 +++++++++++ tests/test_article_only.py | 22 ++++++++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/readability/readability.py b/readability/readability.py index 15c86c1..ddcf49f 100755 --- a/readability/readability.py +++ b/readability/readability.py @@ -276,6 +276,17 @@ def summary(self, html_partial=False, keep_all_images=False): ) if best_candidate: + # Moving a form descendant into the article would bypass + # form removal in sanitize(). + if best_candidate["elem"].xpath("ancestor-or-self::form"): + outside_form = { + elem: candidate + for elem, candidate in candidates.items() + if not elem.xpath("ancestor-or-self::form") + } + if outside_form: + candidates = outside_form + best_candidate = self.select_best_candidate(candidates) article = self.get_article( candidates, best_candidate, html_partial=html_partial ) diff --git a/tests/test_article_only.py b/tests/test_article_only.py index cb8d1ff..edeeb93 100644 --- a/tests/test_article_only.py +++ b/tests/test_article_only.py @@ -577,6 +577,28 @@ def test_preserves_lead_sibling_issue_159(self): self.assertIn(lead, summary) self.assertIn("Eligibility restrictions", summary) + def test_prefers_article_text_to_feedback_form(self): + lead = "The privacy rules explain how public agencies must handle personal information." + details = "People can request access to their records and ask an agency to correct an error." + feedback = "Tell us about your visit, your rating, your questions, your suggestions." + sample = f""" + +

{lead}

{details}

+
+

{feedback}

+

Did you find the guidance, examples, references, or links you needed?

+

Please describe any trouble with navigation, search, layout, or readability.

+ +
+ + """ + + summary = Document(sample).summary() + + self.assertIn(lead, summary) + self.assertIn(details, summary) + self.assertNotIn(feedback, summary) + def test_prefers_list_based_article_to_service_form(self): list_items = "".join( "
  • Article release note number {} with substantial useful "