Merge branch 'dev' into fix/adaptive-autosave-indexerror

This commit is contained in:
Karim shoair
2026-06-07 15:53:47 +03:00
committed by GitHub
20 changed files with 80 additions and 124 deletions
+31 -6
View File
@@ -2,6 +2,7 @@
Tests for Selector.find_similar() with non-default parameters.
Target file: tests/parser/test_general.py (append to TestSimilarElements class)
"""
import pytest
from scrapling import Selector
@@ -61,14 +62,10 @@ class TestFindSimilarAdvanced:
first = product_page.css("div.product")[0]
# Ignore both data-price and data-category → only class matters → all 3 divs match
ignore_all_data = first.find_similar(
similarity_threshold=0.2,
ignore_attributes=["data-price", "data-category"]
similarity_threshold=0.2, ignore_attributes=["data-price", "data-category"]
)
# Ignore nothing → data-category difference (fruit vs veggie) may reduce matches
ignore_nothing = first.find_similar(
similarity_threshold=0.9,
ignore_attributes=[]
)
ignore_nothing = first.find_similar(similarity_threshold=0.9, ignore_attributes=[])
assert len(ignore_all_data) >= len(ignore_nothing)
def test_find_similar_on_text_node_returns_empty(self, product_page):
@@ -76,3 +73,31 @@ class TestFindSimilarAdvanced:
text_node = product_page.css(".name::text")[0]
result = text_node.find_similar()
assert len(result) == 0
def test_find_similar_attribute_count_mismatch_scoring(self):
"""The similarity denominator uses max() of both attribute counts, so candidates
with fewer attributes don't get inflated scores and candidates with extra
attributes stay penalized."""
html = """
<html><body>
<div class="cards">
<div class="card" data-kind="primary" data-color="red" data-size="large">Alpha</div>
<div class="card">Beta</div>
<div class="card" data-kind="primary" data-color="red" data-size="large" data-id="x">Gamma</div>
<div class="card" data-kind="primary" data-color="red" data-size="large">Delta</div>
</div>
</body></html>
"""
page = Selector(html, adaptive=False)
first = page.css("div.card")[0] # Alpha
similar = first.find_similar(similarity_threshold=0.9, ignore_attributes=[])
texts = {el.text for el in similar}
# An exact attribute match must pass
assert "Delta" in texts
# Beta matches 1 of Alpha's 4 attributes; the old denominator counted candidate
# attributes only, inflating it to a perfect score (1.0 / 1)
assert "Beta" not in texts
# Gamma's extra attribute dilutes the score (4.0 / 5) - the intentional penalty
assert "Gamma" not in texts