79 lines
3.7 KiB
Python
79 lines
3.7 KiB
Python
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()
|