Fix Gewobag: use Wohnungshelden iframe like Degewo
- Gewobag has Wohnungshelden iframe embedded on listing page - Navigate directly to iframe URL - Fill form fields: firstName, lastName, email, phone-number - Submit button: 'Anfrage versenden'
This commit is contained in:
parent
180666c781
commit
f0a21bd5f4
1 changed files with 146 additions and 13 deletions
159
monitor.py
159
monitor.py
|
|
@ -606,6 +606,11 @@ class ApplicationHandler:
|
||||||
return result
|
return result
|
||||||
|
|
||||||
async def _apply_gewobag(self, listing: dict, result: dict) -> dict:
|
async def _apply_gewobag(self, listing: dict, result: dict) -> dict:
|
||||||
|
"""
|
||||||
|
Gewobag uses Wohnungshelden (app.wohnungshelden.de) for their application system.
|
||||||
|
The application form is embedded in an iframe on the listing page.
|
||||||
|
We navigate directly to the iframe URL to fill the form.
|
||||||
|
"""
|
||||||
page = await self.context.new_page()
|
page = await self.context.new_page()
|
||||||
try:
|
try:
|
||||||
logger.info(f"[GEWOBAG] Opening page: {listing['link']}")
|
logger.info(f"[GEWOBAG] Opening page: {listing['link']}")
|
||||||
|
|
@ -621,25 +626,153 @@ class ApplicationHandler:
|
||||||
await asyncio.sleep(1)
|
await asyncio.sleep(1)
|
||||||
except: pass
|
except: pass
|
||||||
|
|
||||||
logger.info("[GEWOBAG] Looking for application button...")
|
# Gewobag has Wohnungshelden iframe directly on the page
|
||||||
apply_btn = await page.query_selector('a:has-text("Kontakt"), button:has-text("Anfrage"), a.btn:has-text("Anfragen")')
|
logger.info("[GEWOBAG] Looking for Wohnungshelden iframe...")
|
||||||
if apply_btn and await apply_btn.is_visible():
|
iframe_element = await page.query_selector('iframe[src*="wohnungshelden.de"]')
|
||||||
logger.info("[GEWOBAG] Found application button, clicking...")
|
|
||||||
await apply_btn.click()
|
if iframe_element:
|
||||||
await asyncio.sleep(2)
|
iframe_url = await iframe_element.get_attribute('src')
|
||||||
|
logger.info(f"[GEWOBAG] Found Wohnungshelden iframe: {iframe_url}")
|
||||||
|
|
||||||
screenshot_path = DATA_DIR / f"gewobag_{listing['id']}.png"
|
# Navigate to the iframe URL directly in a new page
|
||||||
await page.screenshot(path=str(screenshot_path))
|
iframe_page = await self.context.new_page()
|
||||||
logger.info(f"[GEWOBAG] Saved screenshot to {screenshot_path}")
|
try:
|
||||||
|
await iframe_page.goto(iframe_url, wait_until="networkidle")
|
||||||
|
await asyncio.sleep(2)
|
||||||
|
logger.info("[GEWOBAG] Loaded Wohnungshelden application page")
|
||||||
|
|
||||||
result["success"] = False
|
# Take screenshot
|
||||||
result["message"] = "Application page opened but not submitted (not implemented)"
|
screenshot_path = DATA_DIR / f"gewobag_wohnungshelden_{listing['id']}.png"
|
||||||
|
await iframe_page.screenshot(path=str(screenshot_path), full_page=True)
|
||||||
|
logger.info(f"[GEWOBAG] Saved Wohnungshelden screenshot")
|
||||||
|
|
||||||
|
# Fill out Wohnungshelden form (same fields as Degewo)
|
||||||
|
form_filled = False
|
||||||
|
|
||||||
|
# Anrede (Salutation) - ng-select dropdown
|
||||||
|
try:
|
||||||
|
salutation_dropdown = await iframe_page.query_selector('#salutation-dropdown, ng-select[id*="salutation"]')
|
||||||
|
if salutation_dropdown:
|
||||||
|
await salutation_dropdown.click()
|
||||||
|
await asyncio.sleep(0.5)
|
||||||
|
anrede_option = await iframe_page.query_selector(f'.ng-option:has-text("{FORM_ANREDE}")')
|
||||||
|
if anrede_option:
|
||||||
|
await anrede_option.click()
|
||||||
|
logger.info(f"[GEWOBAG] Selected Anrede: {FORM_ANREDE}")
|
||||||
|
form_filled = True
|
||||||
|
except Exception as e:
|
||||||
|
logger.warning(f"[GEWOBAG] Could not set Anrede: {e}")
|
||||||
|
|
||||||
|
# Vorname (First name)
|
||||||
|
try:
|
||||||
|
vorname_field = await iframe_page.query_selector('#firstName')
|
||||||
|
if vorname_field:
|
||||||
|
await vorname_field.fill(FORM_VORNAME)
|
||||||
|
logger.info(f"[GEWOBAG] Filled Vorname: {FORM_VORNAME}")
|
||||||
|
form_filled = True
|
||||||
|
except Exception as e:
|
||||||
|
logger.warning(f"[GEWOBAG] Could not fill Vorname: {e}")
|
||||||
|
|
||||||
|
# Nachname (Last name)
|
||||||
|
try:
|
||||||
|
nachname_field = await iframe_page.query_selector('#lastName')
|
||||||
|
if nachname_field:
|
||||||
|
await nachname_field.fill(FORM_NACHNAME)
|
||||||
|
logger.info(f"[GEWOBAG] Filled Nachname: {FORM_NACHNAME}")
|
||||||
|
form_filled = True
|
||||||
|
except Exception as e:
|
||||||
|
logger.warning(f"[GEWOBAG] Could not fill Nachname: {e}")
|
||||||
|
|
||||||
|
# E-Mail
|
||||||
|
try:
|
||||||
|
email_field = await iframe_page.query_selector('#email')
|
||||||
|
if email_field:
|
||||||
|
await email_field.fill(FORM_EMAIL)
|
||||||
|
logger.info(f"[GEWOBAG] Filled E-Mail: {FORM_EMAIL}")
|
||||||
|
form_filled = True
|
||||||
|
except Exception as e:
|
||||||
|
logger.warning(f"[GEWOBAG] Could not fill E-Mail: {e}")
|
||||||
|
|
||||||
|
# Telefonnummer - Gewobag uses #phone-number
|
||||||
|
try:
|
||||||
|
tel_field = await iframe_page.query_selector('#phone-number, input[id*="telefonnummer"], input[id*="phone"]')
|
||||||
|
if tel_field:
|
||||||
|
await tel_field.fill(FORM_PHONE)
|
||||||
|
logger.info(f"[GEWOBAG] Filled Telefon: {FORM_PHONE}")
|
||||||
|
form_filled = True
|
||||||
|
except Exception as e:
|
||||||
|
logger.warning(f"[GEWOBAG] Could not fill Telefon: {e}")
|
||||||
|
|
||||||
|
# Anzahl einziehende Personen - Gewobag uses formly_*_gesamtzahl
|
||||||
|
try:
|
||||||
|
personen_field = await iframe_page.query_selector('input[id*="gesamtzahl"], input[id*="numberPersonsTotal"]')
|
||||||
|
if personen_field:
|
||||||
|
await personen_field.fill(FORM_PERSONS)
|
||||||
|
logger.info(f"[GEWOBAG] Filled Anzahl Personen: {FORM_PERSONS}")
|
||||||
|
form_filled = True
|
||||||
|
except Exception as e:
|
||||||
|
logger.warning(f"[GEWOBAG] Could not fill Anzahl Personen: {e}")
|
||||||
|
|
||||||
|
await asyncio.sleep(1)
|
||||||
|
|
||||||
|
# Screenshot after filling
|
||||||
|
screenshot_path = DATA_DIR / f"gewobag_filled_{listing['id']}.png"
|
||||||
|
await iframe_page.screenshot(path=str(screenshot_path), full_page=True)
|
||||||
|
logger.info(f"[GEWOBAG] Saved filled form screenshot")
|
||||||
|
|
||||||
|
# Try to submit
|
||||||
|
if form_filled:
|
||||||
|
try:
|
||||||
|
submit_selectors = [
|
||||||
|
'button[type="submit"]',
|
||||||
|
'button:has-text("Absenden")',
|
||||||
|
'button:has-text("Senden")',
|
||||||
|
'button:has-text("Anfrage")',
|
||||||
|
'.btn-primary',
|
||||||
|
]
|
||||||
|
|
||||||
|
submit_btn = None
|
||||||
|
for selector in submit_selectors:
|
||||||
|
submit_btn = await iframe_page.query_selector(selector)
|
||||||
|
if submit_btn and await submit_btn.is_visible():
|
||||||
|
logger.info(f"[GEWOBAG] Found submit button: {selector}")
|
||||||
|
break
|
||||||
|
submit_btn = None
|
||||||
|
|
||||||
|
if submit_btn:
|
||||||
|
await submit_btn.click()
|
||||||
|
logger.info("[GEWOBAG] Clicked submit button")
|
||||||
|
await asyncio.sleep(3)
|
||||||
|
|
||||||
|
# Screenshot after submission
|
||||||
|
screenshot_path = DATA_DIR / f"gewobag_submitted_{listing['id']}.png"
|
||||||
|
await iframe_page.screenshot(path=str(screenshot_path), full_page=True)
|
||||||
|
logger.info(f"[GEWOBAG] Saved submission screenshot")
|
||||||
|
|
||||||
|
result["success"] = True
|
||||||
|
result["message"] = "Application submitted via Wohnungshelden"
|
||||||
|
else:
|
||||||
|
result["success"] = False
|
||||||
|
result["message"] = "Form filled but submit button not found"
|
||||||
|
logger.warning("[GEWOBAG] Submit button not found")
|
||||||
|
except Exception as e:
|
||||||
|
result["success"] = False
|
||||||
|
result["message"] = f"Submit error: {str(e)}"
|
||||||
|
logger.warning(f"[GEWOBAG] Submit error: {e}")
|
||||||
|
else:
|
||||||
|
result["success"] = False
|
||||||
|
result["message"] = "No form fields found in Wohnungshelden"
|
||||||
|
logger.warning("[GEWOBAG] Could not find form fields")
|
||||||
|
finally:
|
||||||
|
await iframe_page.close()
|
||||||
else:
|
else:
|
||||||
result["message"] = "No application button found"
|
result["success"] = False
|
||||||
logger.warning("[GEWOBAG] Could not find application button")
|
result["message"] = "No Wohnungshelden iframe found"
|
||||||
|
logger.warning("[GEWOBAG] No Wohnungshelden iframe found")
|
||||||
screenshot_path = DATA_DIR / f"gewobag_nobtn_{listing['id']}.png"
|
screenshot_path = DATA_DIR / f"gewobag_nobtn_{listing['id']}.png"
|
||||||
await page.screenshot(path=str(screenshot_path))
|
await page.screenshot(path=str(screenshot_path))
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
result["success"] = False
|
||||||
result["message"] = f"Error: {str(e)}"
|
result["message"] = f"Error: {str(e)}"
|
||||||
logger.error(f"[GEWOBAG] Exception: {str(e)}")
|
logger.error(f"[GEWOBAG] Exception: {str(e)}")
|
||||||
finally:
|
finally:
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue