from playwright.sync_api import sync_playwright import json, time, re def run(): with sync_playwright() as p: try: browser = p.chromium.connect_over_cdp('http://127.0.0.1:9222') page = browser.contexts[0].pages[0] page.goto('https://my.dom.gosuslugi.ru/citizen-cabinet/#!/appeals/applicant/search') page.wait_for_load_state('networkidle') time.sleep(10) # Закрываем мешающие диалоги (Restore session и т.д.) try: page.keyboard.press('Escape') time.sleep(2) except: pass # Пытаемся выставить 'По 100' через JavaScript (самый надежный способ в SPA) try: # В ГИС ЖКХ это обычно Angular-компонент. Попробуем найти селект по значению. page.evaluate('''() => { const selectors = document.querySelectorAll('select, .ui-select-container'); for (const s of selectors) { if (s.innerText.includes('10')) { s.click(); } } }''') time.sleep(2) page.get_by_text('100').click() print('Выставлено по 100 на странице.') time.sleep(10) except Exception as e: print(f'Не удалось выставить "по 100" программно: {e}') full_queue = [] while True: # Убираем оверлеи если они есть page.evaluate('''() => { document.querySelectorAll('.p-dialog-mask, .modal-backdrop').forEach(el => el.remove()); document.body.classList.remove('p-overflow-hidden'); }''') rows = page.locator('tr').all() for row in rows: text = row.inner_text() if '73-20' in text: link = row.locator('a[href*="appeals/view/"]').first num_match = re.search(r'73-202\d-\d+', text) num = num_match.group(0) if num_match else f"unknown_{time.time()}" href = link.get_attribute('href') if href and num not in [x['number'] for x in full_queue]: full_queue.append({'number': num, 'href': href}) next_btn = page.locator('a:has-text("следующая")').first if next_btn.is_visible() and next_btn.is_enabled(): print(f'Переход на следующую страницу... Уже собрано: {len(full_queue)}') # Кликаем принудительно через JS если обычный клик перехвачен page.evaluate('el => el.click()', next_btn.element_handle()) page.wait_for_load_state('networkidle') time.sleep(10) else: break # Сохраняем в официальную папку сервиса output_path = '/app/services/gis_harvester/data/full_queue.json' with open(output_path, 'w', encoding='utf-8') as f: json.dump(full_queue, f, ensure_ascii=False, indent=2) print(f'ИТОГО СОБРАНО: {len(full_queue)} целей.') browser.close() except Exception as e: print(f'ERROR: {e}') if __name__ == "__main__": run()