feat: AR-House initial commit
This commit is contained in:
@@ -0,0 +1,145 @@
|
||||
"""scripts/probe_civitek.py — exploratory probe of Civitek OCRS flow.
|
||||
|
||||
NO production code. Just maps the click sequence + DOM for civitek_ocrs.py.
|
||||
|
||||
Usage:
|
||||
python scripts/probe_civitek.py
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import sys
|
||||
import time
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
def probe():
|
||||
from playwright.sync_api import sync_playwright
|
||||
|
||||
out_dir = Path(__file__).parent.parent / "_probe_out" / "civitek"
|
||||
out_dir.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
with sync_playwright() as p:
|
||||
browser = p.chromium.launch(headless=True)
|
||||
context = browser.new_context(
|
||||
user_agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 Chrome/120",
|
||||
)
|
||||
page = context.new_page()
|
||||
|
||||
# STEP 1: County entry page (Hernando = 27)
|
||||
print("[1] GET county entry page...")
|
||||
page.goto("https://www.civitekflorida.com/ocrs/county/27/", wait_until="networkidle")
|
||||
print(f" Title: {page.title()}")
|
||||
print(f" URL: {page.url}")
|
||||
(out_dir / "01_entry.html").write_text(page.content(), encoding="utf-8")
|
||||
|
||||
# STEP 2: Click "Public" button
|
||||
print("\n[2] Click 'Public' button...")
|
||||
public_btn = page.locator("button:has-text('Public')").first
|
||||
print(f" Public button visible: {public_btn.is_visible()}")
|
||||
public_btn.click()
|
||||
page.wait_for_timeout(3000) # JSF AJAX settle
|
||||
print(f" After click URL: {page.url}")
|
||||
print(f" After click title: {page.title()}")
|
||||
(out_dir / "02_after_public.html").write_text(page.content(), encoding="utf-8")
|
||||
|
||||
# STEP 3: Look for disclaimer / accept
|
||||
body_text = page.inner_text("body")[:2000]
|
||||
print(f"\n[3] Page body snippet (first 800 chars):\n{body_text[:800]}")
|
||||
|
||||
# Check for common disclaimer button names
|
||||
for txt in ["Accept", "I Accept", "I Agree", "Agree", "Continue"]:
|
||||
loc = page.locator(f"button:has-text('{txt}'), input[type=submit][value*='{txt}']")
|
||||
count = loc.count()
|
||||
if count > 0:
|
||||
print(f" Found '{txt}' button: {count} match(es)")
|
||||
|
||||
# STEP 4: Look for search form fields
|
||||
print("\n[4] Form fields on current page:")
|
||||
inputs = page.locator("input").all()
|
||||
for i, inp in enumerate(inputs[:30]):
|
||||
try:
|
||||
name = inp.get_attribute("name") or ""
|
||||
type_ = inp.get_attribute("type") or ""
|
||||
value = (inp.get_attribute("value") or "")[:30]
|
||||
placeholder = inp.get_attribute("placeholder") or ""
|
||||
if type_ in ("hidden",) and not name.startswith("javax"):
|
||||
continue
|
||||
if type_ == "hidden":
|
||||
continue
|
||||
print(f" [{i}] name={name!r} type={type_!r} value={value!r} placeholder={placeholder!r}")
|
||||
except Exception as e:
|
||||
print(f" [{i}] error: {e}")
|
||||
|
||||
print("\n[5] Buttons on page:")
|
||||
buttons = page.locator("button, input[type=submit]").all()
|
||||
for i, btn in enumerate(buttons[:15]):
|
||||
try:
|
||||
txt = (btn.inner_text() or btn.get_attribute("value") or "").strip()[:50]
|
||||
btn_id = btn.get_attribute("id") or ""
|
||||
print(f" [{i}] text={txt!r} id={btn_id!r}")
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
# Snapshot
|
||||
page.screenshot(path=str(out_dir / "02_after_public.png"), full_page=True)
|
||||
|
||||
# STEP 6: Click "I Agree" disclaimer
|
||||
print("\n[6] Click 'I Agree'...")
|
||||
agree = page.locator("button:has-text('I Agree')").first
|
||||
if agree.count() > 0:
|
||||
agree.click()
|
||||
page.wait_for_timeout(3000) # JSF AJAX settle
|
||||
print(f" After agree URL: {page.url}")
|
||||
(out_dir / "03_after_agree.html").write_text(page.content(), encoding="utf-8")
|
||||
page.screenshot(path=str(out_dir / "03_after_agree.png"), full_page=True)
|
||||
|
||||
print("\n[7] Search form fields after disclaimer:")
|
||||
for inp in page.locator("input, select").all()[:40]:
|
||||
try:
|
||||
tag = inp.evaluate("el => el.tagName.toLowerCase()")
|
||||
name = inp.get_attribute("name") or ""
|
||||
type_ = inp.get_attribute("type") or ""
|
||||
id_ = inp.get_attribute("id") or ""
|
||||
placeholder = inp.get_attribute("placeholder") or ""
|
||||
label_for = ""
|
||||
if id_:
|
||||
lbl = page.locator(f"label[for='{id_}']").first
|
||||
if lbl.count() > 0:
|
||||
label_for = lbl.inner_text()[:50]
|
||||
if type_ == "hidden":
|
||||
continue
|
||||
print(f" <{tag}> id={id_!r} name={name!r} type={type_!r} placeholder={placeholder!r} label={label_for!r}")
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
print("\n[8] Buttons after disclaimer:")
|
||||
for btn in page.locator("button, input[type=submit]").all()[:20]:
|
||||
try:
|
||||
txt = (btn.inner_text() or btn.get_attribute("value") or "").strip()[:50]
|
||||
btn_id = btn.get_attribute("id") or ""
|
||||
print(f" text={txt!r} id={btn_id!r}")
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
print("\n[9] Links / nav after disclaimer (first 20):")
|
||||
for a in page.locator("a").all()[:20]:
|
||||
try:
|
||||
txt = (a.inner_text() or "").strip()[:60]
|
||||
href = a.get_attribute("href") or ""
|
||||
if txt:
|
||||
print(f" {txt!r} → {href[:80]}")
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
print(f"\n[OK] Screenshots and HTML saved to {out_dir}/")
|
||||
browser.close()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
try:
|
||||
probe()
|
||||
except Exception as e:
|
||||
import traceback
|
||||
print(f"ERROR: {e}", file=sys.stderr)
|
||||
traceback.print_exc()
|
||||
sys.exit(1)
|
||||
Reference in New Issue
Block a user