103 lines
3.8 KiB
Python
103 lines
3.8 KiB
Python
"""Inspeccionar el submit real: que pasa cuando llenamos el form y clickeamos Search."""
|
|
from __future__ import annotations
|
|
import io, sys, time
|
|
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding="utf-8", errors="replace")
|
|
|
|
from playwright.sync_api import sync_playwright
|
|
|
|
USER_AGENT = "AR-House/1.0 (real estate investment analysis)"
|
|
|
|
with sync_playwright() as p:
|
|
browser = p.chromium.launch(headless=True)
|
|
context = browser.new_context(user_agent=USER_AGENT)
|
|
page = context.new_page()
|
|
page.set_default_timeout(20_000)
|
|
|
|
# Capture console + network errors
|
|
page.on("console", lambda msg: print(f" CONSOLE [{msg.type}]: {msg.text[:200]}"))
|
|
page.on("pageerror", lambda err: print(f" PAGEERROR: {err}"))
|
|
|
|
page.goto("https://paopropertysearch.coj.net/Basic/Search.aspx", wait_until="domcontentloaded")
|
|
print("Loaded:", page.url)
|
|
|
|
# Llenar form
|
|
page.locator("#ctl00_cphBody_tbStreetNumber").fill("3245")
|
|
print("Street # filled")
|
|
|
|
# Inspeccionar opciones del dropdown direction
|
|
print("\nDirection options:")
|
|
opts = page.locator("#ctl00_cphBody_ddStreetPrefix option").all()
|
|
for o in opts[:15]:
|
|
val = o.get_attribute("value") or ""
|
|
txt = (o.text_content() or "").strip()
|
|
print(f" value='{val}' text='{txt}'")
|
|
|
|
print("\nSuffix options:")
|
|
opts = page.locator("#ctl00_cphBody_ddStreetSuffix option").all()
|
|
for o in opts[:30]:
|
|
val = o.get_attribute("value") or ""
|
|
txt = (o.text_content() or "").strip()
|
|
print(f" value='{val}' text='{txt}'")
|
|
|
|
# Probar select N (direction)
|
|
try:
|
|
page.locator("#ctl00_cphBody_ddStreetPrefix").select_option(value="N")
|
|
print("Direction N selected")
|
|
except Exception as e:
|
|
print(f"Direction N select FAILED: {e}")
|
|
|
|
page.locator("#ctl00_cphBody_tbStreetName").fill("PEARL")
|
|
print("Street name PEARL filled")
|
|
|
|
try:
|
|
page.locator("#ctl00_cphBody_ddStreetSuffix").select_option(value="ST")
|
|
print("Suffix ST selected")
|
|
except Exception as e:
|
|
print(f"Suffix select FAILED: {e}")
|
|
|
|
# Click Search
|
|
print("\nClicking Search...")
|
|
page.locator("#ctl00_cphBody_bSearch").click()
|
|
|
|
# Wait a few seconds and capture state
|
|
time.sleep(4)
|
|
|
|
print("\nPost-click URL:", page.url)
|
|
print("Post-click title:", page.title())
|
|
|
|
# Dump for inspection
|
|
html = page.content()
|
|
with open("scripts/_duval_pa_after_submit.html", "w", encoding="utf-8") as f:
|
|
f.write(html)
|
|
print(f"HTML saved: scripts/_duval_pa_after_submit.html ({len(html):,} chars)")
|
|
|
|
# Buscar error messages explícitos
|
|
for sel in [".error", "#error", "[class*='error']", "[class*='alert']", ".validation-summary"]:
|
|
try:
|
|
count = page.locator(sel).count()
|
|
if count > 0:
|
|
for i in range(min(count, 5)):
|
|
txt = (page.locator(sel).nth(i).text_content() or "").strip()
|
|
if txt:
|
|
print(f" ERR [{sel}]: {txt[:200]}")
|
|
except Exception:
|
|
pass
|
|
|
|
# Buscar table de resultados
|
|
tables = page.locator("table").all()
|
|
print(f"\nFound {len(tables)} tables on results page")
|
|
for i, t in enumerate(tables[:5]):
|
|
try:
|
|
rows = t.locator("tr").all()
|
|
if len(rows) > 1:
|
|
print(f" Table [{i}] has {len(rows)} rows. First row:")
|
|
first_cells = rows[0].locator("td, th").all()[:8]
|
|
print(f" Headers: {[c.text_content().strip()[:30] for c in first_cells]}")
|
|
if len(rows) > 1:
|
|
data_cells = rows[1].locator("td").all()[:8]
|
|
print(f" Row 1: {[c.text_content().strip()[:30] for c in data_cells]}")
|
|
except Exception as e:
|
|
print(f" Table [{i}] error: {e}")
|
|
|
|
browser.close()
|