fix(auditing): reject call-tracking placeholders in website phone extraction

_valid_phone() rejects all-same-digit numbers (999-999-9999, 000-000-0000)
that call-tracking widgets emit before they are wired; _phone_from_text now
scans past an invalid first match instead of returning it. Selftest covers
placeholder rejection and visible-text-wins-over-tel: semantics.
This commit is contained in:
2026-08-15 17:54:03 +00:00
parent 73204c4810
commit 8bb1d7b791
+22 -6
View File
@@ -130,16 +130,26 @@ async def scrape_google(query, coords, business=""):
return None return None
def _valid_phone(num):
"""10 US digits, not an all-same-digit placeholder (999-999-9999, the
value call-tracking widgets emit before they're wired)."""
d = re.sub(r"\D", "", num)
return len(d) == 10 and len(set(d)) > 1
def _phone_from_text(text): def _phone_from_text(text):
"""First standalone US phone number in rendered text. """First standalone, non-placeholder US phone number in rendered text.
Lookarounds reject a phone-like substring glued to other digits (the Lookarounds reject a phone-like substring glued to other digits (the
raw-HTML path that previously returned JS artifact numbers). raw-HTML path that previously returned JS artifact numbers);
_valid_phone rejects all-same-digit call-tracking placeholders.
""" """
m = re.search(r"(?<!\d)(\(\d{3}\)\s*\d{3}[-.]\d{4})(?!\d)", text) for pat in (r"(?<!\d)(\(\d{3}\)\s*\d{3}[-.]\d{4})(?!\d)",
if not m: r"(?<!\d)(\d{3}[-.]\d{3}[-.]\d{4})(?!\d)"):
m = re.search(r"(?<!\d)(\d{3}[-.]\d{3}[-.]\d{4})(?!\d)", text) for mm in re.finditer(pat, text):
return m.group(1) if m else None if _valid_phone(mm.group(1)):
return mm.group(1)
return None
def _jina_markdown(website_url): def _jina_markdown(website_url):
@@ -395,6 +405,12 @@ def _selftest():
# JS artifact: phone-like substring glued to other digits -> reject # JS artifact: phone-like substring glued to other digits -> reject
assert _phone_from_text("var id=1234567890123;") is None assert _phone_from_text("var id=1234567890123;") is None
assert _phone_from_text("no numbers here") is None assert _phone_from_text("no numbers here") is None
# call-tracking placeholder (all-same digit) -> reject
assert _phone_from_text("Call (999) 999-9999 now") is None
# visible text wins over tel: href (audit semantics: report what's displayed;
# tel: vs visible discrepancies are audit FINDINGS, not extraction noise)
txt = 'Call: (916) 238-3838 <a href="tel:9165716448">call</a>'
assert _phone_from_text(txt) == "(916) 238-3838"
print("[SELFTEST] phone extraction: PASS") print("[SELFTEST] phone extraction: PASS")