fix(siska): kafelki z apostrofem w tytule i kilka osob w jednym nazwisku
Some checks are pending
Backend tests / test (push) Waiting to run
Some checks are pending
Backend tests / test (push) Waiting to run
Strona nie escapuje apostrofu w title/alt, wiec "Brenna's Mouths" urywal
dopasowanie i kafelek wypadal (3 z 18 na stronie). Pierwszy czlon alt z
kilkoma osobami ("A, B - Tytul") szedl jako jeden wykonawca.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
9225ae95de
commit
494b15aedd
2 changed files with 53 additions and 9 deletions
|
|
@ -45,14 +45,16 @@ _BASE = "https://siska.tv"
|
||||||
_HOST_RE = re.compile(r"^https://(?:www\.)?siska\.(?:tv|video)/", re.IGNORECASE)
|
_HOST_RE = re.compile(r"^https://(?:www\.)?siska\.(?:tv|video)/", re.IGNORECASE)
|
||||||
|
|
||||||
# Kafelek: <a title='..' href='..videoID=N'>. Reszta pól w oknie po tym matchu.
|
# Kafelek: <a title='..' href='..videoID=N'>. Reszta pól w oknie po tym matchu.
|
||||||
|
# Strona nie escapuje apostrofu w atrybutach (title='Brenna's Mouths'), wiec wartosc
|
||||||
|
# konczy sie na apostrofie, po ktorym idzie nastepny atrybut, a nie na pierwszym.
|
||||||
_A_RE = re.compile(
|
_A_RE = re.compile(
|
||||||
r"<a\s+title='(?P<title>[^']*)'\s+"
|
r"<a\s+title='(?P<title>[^<>]*?)'\s+"
|
||||||
r"href='(?P<url>https://(?:www\.)?siska\.(?:tv|video)/video\.php\?videoID=\d+)'",
|
r"href='(?P<url>https://(?:www\.)?siska\.(?:tv|video)/video\.php\?videoID=\d+)'",
|
||||||
re.IGNORECASE,
|
re.IGNORECASE,
|
||||||
)
|
)
|
||||||
_DUR_RE = re.compile(r"th_video_duration'>\s*([\d]{1,2}(?:\s*:\s*[\d]{2}){1,2})\s*<")
|
_DUR_RE = re.compile(r"th_video_duration'>\s*([\d]{1,2}(?:\s*:\s*[\d]{2}){1,2})\s*<")
|
||||||
_THUMB_RE = re.compile(r"data-src='([^']+\.(?:jpg|jpeg|webp|png))'", re.IGNORECASE)
|
_THUMB_RE = re.compile(r"data-src='([^']+\.(?:jpg|jpeg|webp|png))'", re.IGNORECASE)
|
||||||
_ALT_RE = re.compile(r"alt='([^']*)'")
|
_ALT_RE = re.compile(r"alt='([^<>]*?)'(?=\s+[\w-]+=|\s*/?>)")
|
||||||
_CAT_RE = re.compile(r"/category/([^/]+)/", re.IGNORECASE)
|
_CAT_RE = re.compile(r"/category/([^/]+)/", re.IGNORECASE)
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -122,21 +124,22 @@ class SiskaScraper(BaseBrowseScraper):
|
||||||
thumbnail_url = _canonical(tm.group(1)) if tm else None
|
thumbnail_url = _canonical(tm.group(1)) if tm else None
|
||||||
|
|
||||||
# alt='Performer - Tytuł - Studio' → performer (pierwszy), studio (ostatni).
|
# alt='Performer - Tytuł - Studio' → performer (pierwszy), studio (ostatni).
|
||||||
|
# Kilka osob stoi w pierwszym czlonie po przecinku ("A, B - Tytul").
|
||||||
performers: list[RawPerformer] = []
|
performers: list[RawPerformer] = []
|
||||||
studio: RawStudio | None = None
|
studio: RawStudio | None = None
|
||||||
am = _ALT_RE.search(window)
|
am = _ALT_RE.search(window)
|
||||||
if am and " - " in am.group(1):
|
if am and " - " in am.group(1):
|
||||||
parts = [p.strip() for p in am.group(1).split(" - ") if p.strip()]
|
parts = [p.strip() for p in am.group(1).split(" - ") if p.strip()]
|
||||||
if len(parts) >= 2:
|
if len(parts) >= 2:
|
||||||
pname = parts[0]
|
|
||||||
sname = parts[-1]
|
sname = parts[-1]
|
||||||
if pname:
|
for pname in (n.strip() for n in parts[0].split(",")):
|
||||||
performers.append(
|
if pname:
|
||||||
RawPerformer(
|
performers.append(
|
||||||
external_id=f"{self.sitetag}:performer:{_slugify(pname)}",
|
RawPerformer(
|
||||||
name=pname,
|
external_id=f"{self.sitetag}:performer:{_slugify(pname)}",
|
||||||
|
name=pname,
|
||||||
|
)
|
||||||
)
|
)
|
||||||
)
|
|
||||||
if sname and len(parts) >= 3:
|
if sname and len(parts) >= 3:
|
||||||
studio = RawStudio(
|
studio = RawStudio(
|
||||||
external_id=f"{self.sitetag}:studio:{_slugify(sname)}",
|
external_id=f"{self.sitetag}:studio:{_slugify(sname)}",
|
||||||
|
|
|
||||||
41
tests/test_siska_listing.py
Normal file
41
tests/test_siska_listing.py
Normal file
|
|
@ -0,0 +1,41 @@
|
||||||
|
from app.connectors.direct_scrapers import siska
|
||||||
|
from app.connectors.direct_scrapers.siska import SiskaScraper
|
||||||
|
|
||||||
|
# Dwa kafelki jak na siska.tv 2026-09-27; pierwszy z nieescapowanym apostrofem.
|
||||||
|
_LISTING = """
|
||||||
|
<li class='pure-u-1-3'><div class='back'><div class='thumb'><div class='rel'>
|
||||||
|
<a title=' Filling Chanel and Brenna's Mouths' href='https://siska.tv/video.php?videoID=226988' class='video-thumb'><span class='icon-hd'></span><span class='th_video_duration'>36 : 58</span><span class='th_photo_count'><span class='ico-photo'></span></span><img src='data:image/png;base64,R0lGOD' data-src='https://siska.tv/category/Deep-Throat/1049123346.jpg' width='640' height='360' alt='Chanel Camryn, Brenna McKenna - Filling Chanel and Brenna's Mouths' class='pure-img padding' /></a></div>
|
||||||
|
</div></div></li>
|
||||||
|
<li class='pure-u-1-3'><div class='back'><div class='thumb'><div class='rel'>
|
||||||
|
<a title='Plain Title' href='https://www.siska.video/video.php?videoID=226987' class='video-thumb'><span class='th_video_duration'>1 : 02 : 03</span><img data-src='https://siska.tv/category/Anal/1049123345.jpg' alt='Jane Doe - Plain Title - Some Studio' class='pure-img' /></a></div>
|
||||||
|
</div></div></li>
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
class _Res:
|
||||||
|
text = _LISTING
|
||||||
|
|
||||||
|
|
||||||
|
def _crawl(monkeypatch):
|
||||||
|
monkeypatch.setattr(siska, "browser_get", lambda url, timeout=None: _Res())
|
||||||
|
monkeypatch.setattr(siska, "compute_thumbnail_phash", lambda *a, **k: None)
|
||||||
|
return SiskaScraper().crawl_page(1)
|
||||||
|
|
||||||
|
|
||||||
|
def test_apostrophe_in_title_keeps_tile(monkeypatch):
|
||||||
|
scenes = _crawl(monkeypatch)
|
||||||
|
assert [s.url for s in scenes] == [
|
||||||
|
"https://siska.tv/video.php?videoID=226988",
|
||||||
|
"https://siska.tv/video.php?videoID=226987",
|
||||||
|
]
|
||||||
|
assert scenes[0].title == "Filling Chanel and Brenna's Mouths"
|
||||||
|
assert scenes[0].duration_sec == 36 * 60 + 58
|
||||||
|
|
||||||
|
|
||||||
|
def test_comma_separated_performers_are_split(monkeypatch):
|
||||||
|
first, second = _crawl(monkeypatch)
|
||||||
|
assert [p.name for p in first.performers] == ["Chanel Camryn", "Brenna McKenna"]
|
||||||
|
# dwa czlony alt = osoby + tytul, studia brak
|
||||||
|
assert first.studio is None
|
||||||
|
assert [p.name for p in second.performers] == ["Jane Doe"]
|
||||||
|
assert second.studio.name == "Some Studio"
|
||||||
Loading…
Add table
Reference in a new issue