← back to Ga Allsites
_verify_ga4_gap.py
34 lines
import json
import pathlib
import re
import ssl
import urllib.request
from concurrent.futures import ThreadPoolExecutor
cand=open("/tmp/ga4_62.txt").read().split()
ctx=ssl.create_default_context(); ctx.check_hostname=False; ctx.verify_mode=ssl.CERT_NONE
# FIX (Cody): add gtm.js (GA4-via-GTM) + analytics.js so GTM-managed sites aren't false NO_GA4
GA4=re.compile(r"(G-[A-Z0-9]{6,}|googletagmanager\.com/gtag/js|googletagmanager\.com/gtm\.js|gtag\('config'|GTM-[A-Z0-9]+|UA-\d{4,}|google-analytics\.com/analytics\.js|dataLayer)")
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,"HAS_GA4" if GA4.search(html) else "NO_GA4")
except Exception:
if s=="http": return (d,"UNREACHABLE")
return (d,"UNREACHABLE")
res=list(ThreadPoolExecutor(max_workers=24).map(probe,cand))
from collections import Counter
c=Counter(x[1] for x in res)
print("RE-VERIFY (with GTM/dataLayer detection):")
for k,v in c.most_common(): print(f" {k:12} {v}")
no=sorted(d for d,s in res if s=="NO_GA4")
unreach=sorted(d for d,s in res if s=="UNREACHABLE")
pathlib.Path("cache/_ga4_inject_targets.json").write_text(json.dumps(no))
pathlib.Path("cache/_ga4_unreachable.json").write_text(json.dumps(unreach)) # FIX: durable record
print(f"\nTRUE inject targets (NO_GA4 even w/ GTM check): {len(no)}")
print(f"UNREACHABLE (saved to cache/_ga4_unreachable.json for a retry): {len(unreach)}")
print("unreachable:", unreach)