← back to Ga Allsites

_track_audit.py

42 lines

import json
import pathlib
import re
import ssl
import urllib.request
from concurrent.futures import ThreadPoolExecutor

sites=[s["domain"] for s in json.load(open("/Users/macstudio3/Projects/domain-landings/data/all-sites.json"))]
ctx=ssl.create_default_context(); ctx.check_hostname=False; ctx.verify_mode=ssl.CERT_NONE
PAT={
 "ga4":  re.compile(r"(gtag/js\?id=G-|gtag\('config',\s*'G-|G-[A-Z0-9]{8,})"),
 "meta": re.compile(r"(connect\.facebook\.net|fbq\('init'|fbevents\.js|facebook.*pixel)",re.IGNORECASE),
 "gads": re.compile(r"(gtag/js\?id=AW-|AW-\d{6,}|googleadservices)"),
 "gtm":  re.compile(r"(googletagmanager\.com/gtm\.js|GTM-[A-Z0-9]+)"),
}
def probe(d):
    for s in ("https","http"):
        try:
            req=urllib.request.Request(f"{s}://{d}/",headers={"User-Agent":"Mozilla/5.0"})
            html=urllib.request.urlopen(req,timeout=12,context=ctx).read(250000).decode("utf-8","ignore")
            return (d,{k:bool(p.search(html)) for k,p in PAT.items()},True)
        except Exception:
            if s=="http": return (d,{},False)
    return (d,{},False)
res=list(ThreadPoolExecutor(max_workers=24).map(probe,sites))
reach=[r for r in res if r[2]]
def pct(k): 
    n=sum(1 for _,f,ok in reach if f.get(k)); return f"{n}/{len(reach)} ({100*n//max(1,len(reach))}%)"
print(f"reachable: {len(reach)}/{len(res)}")
print(f"  GA4:        {pct('ga4')}")
print(f"  Meta pixel: {pct('meta')}")
print(f"  Google Ads: {pct('gads')}")
print(f"  GTM:        {pct('gtm')}")
# who lacks GA4? who lacks meta?
no_ga4=sorted(d for d,f,ok in reach if not f.get('ga4'))
no_meta=sorted(d for d,f,ok in reach if not f.get('meta'))
pathlib.Path("cache/_no_ga4_all.json").write_text(json.dumps(no_ga4))
pathlib.Path("cache/_no_meta_all.json").write_text(json.dumps(no_meta))
print(f"\nreachable sites WITHOUT GA4: {len(no_ga4)}")
print(f"reachable sites WITHOUT Meta pixel: {len(no_meta)} (essentially all — no pixel deployed yet)")
print("no-GA4 sample:", no_ga4[:15])