From 44cf3d3c21154dc32548acb545aeea41fa4ed097 Mon Sep 17 00:00:00 2001 From: Your Name Date: Mon, 26 Jan 2026 15:20:04 +1000 Subject: [PATCH] add files --- config.json | 14 ++ main.py | 383 +++++++++++++++++++++++++++++++++++++++++++++++ requirements.txt | Bin 0 -> 1576 bytes settings_work.py | 39 +++++ work_parser.py | 87 +++++++++++ 5 files changed, 523 insertions(+) create mode 100644 config.json create mode 100644 main.py create mode 100644 requirements.txt create mode 100644 settings_work.py create mode 100644 work_parser.py diff --git a/config.json b/config.json new file mode 100644 index 0000000..1512a4d --- /dev/null +++ b/config.json @@ -0,0 +1,14 @@ +{ + "sources": [ + { + "name": "source1", + "url": "", + "prompt": "Задача: Перевод на русский язык и тематическая фильтрация новостных статей из китайской прессы. \n Необходимо переводить текст статьи и определять, относится ли она к КНР по указанным темам: \n 1. Перевод\n Переведи предоставленный китайский текст на русский язык, сохранив оригинальный смысл, стиль и структуру.\n Текст:\n {content}\n -------------------------------------\n 2. Отбирай исключительно новости, прямо относящиеся к Китаю, его безопасности, соседним странам и территориям, влияющим на интересы Китая.\n Если не относится к Китаю — считаем, что статья НЕ подходит, и отдаем пустой JSON:\n {\"text\": \"\", \"pereskas\": \"\", \"title\": \"\", \"topics\": []}\n Если привязка есть — переходи к шагу 3. \n -------------------------------------\n 3. Тематическая классификация\n Определи, относится ли статья к одной или нескольким темам из списка:\n 1) Военные новости — конфликты, учения, мобилизация, закупки вооружений. \n 2) Пограничная деятельность — охрана границы, пограничные учения, строительство или модернизация пограничной инфраструктуры, техника для пограничников. \n 3) Пункты пропуска на границе с РФ — изменения режима работы, строительство, реконструкция, оборудование, логистика. \n 4) Пограничные реки — состояние рек, экология, инфраструктурные проекты, мониторинг. \n 5) Чрезвычайные ситуации — природные и техногенные происшествия, особенно затрагивающие пограничные реки и прилегающие земли. \n 6) Санитарно-эпидемиологическая обстановка — эпидемии, эпизоотии, эпифитотии, угрозы и меры предотвращения. \n 7) Индустриальные проекты (арктическое/антарктическое направление). \n 8) Индустриальные проекты в приграничных районах — заводы, производства, технопарки, новые технологии. \n 9) Инфраструктурные проекты в приграничных районах — дороги, мосты, транспорт, логистика. \n 10) Культура малочисленных народностей (нанайцы, монголы, уйгуры, нанайцы и хэчжэ) — политика, традиции, бытовая жизнь нанайцев, монголов, уйгуров, и хэчжэ (малочисленных народов).\n\n Отметь только те темы, которым статья действительно соответствует.\n\n -------------------------------------\n 4. Формат ответа \n Вернуть строго JSON без пояснений и дополнительных слов:\n {\n \"translation_text\": \"<перевод текста статьи на русский язык (дословный, точный и без сокращений ) >\",\n \"short_text\": \"<пересказ переведённого текста>\",\n \"title\": \"<краткая суть новости (1–2 предложения)>\",\n \"category\": \"<названий категорий, которым соответствует статья>\"\n }\n Если статья не относится ни к одной теме или не привязана к нужным регионам — вернуть:\n {\"translation_text\": \"\", \"short_text\": \"\", \"title\": \"\", \"category\": \"\"}" + }, + { + "name": "source2", + "url": "https://example2.com/api", + "prompt": "Задача Перевод и тематическая фильтрация новостных статей из китайской прессы.\n Необходимо переводить текст статьи и определять, относится ли она к указанным темам и к одной из следующих административных единиц КНР:\n - провинция Хэйлунцзян\n - провинция Цзилинь\n - провинция Ляонин\n - автономный район Внутренняя Монголия\n\n ВАЖНО Отбирать и классифицировать нужно только те материалы, которые имеют связь с одной из перечисленных провинций/района.\n -------------------------------------\n 1. Перевод\n Переведи предоставленный китайский текст на русский язык, сохранив оригинальный смысл, стиль и структуру.\n Текст:\n {content}\n -------------------------------------\n 2. Проверка географической привязки\n Определи относится ли статья к одной из следующих административных единиц\n - Хэйлунцзян\n - Цзилинь\n - Ляонин\n - Внутренняя Монголия\n Если нет прямого упоминания — считаем что статья НЕ подходит и отдаем пустой JSON\n {\"translation_text\" \"\" \"short_text\" \"\" \"title\" \"\" \"category\" \"\"}\n Если привязка есть — переходи к шагу 3.\n -------------------------------------\n 3. Тематическая классификация\n Определи относится ли статья к одной или нескольким темам из списка\n 1) Военные новости — конфликты, учения, мобилизация, закупки вооружений.\n 2) Пограничная деятельность — охрана границы, пограничные учения, строительство или модернизация пограничной инфраструктуры, техника для пограничников.\n 3) Пункты пропуска на границе с РФ — изменения режима работы, строительство, реконструкция, оборудование, логистика.\n 4) Пограничные реки — состояние рек, экология, инфраструктурные проекты, мониторинг.\n 5) Чрезвычайные ситуации — природные и техногенные происшествия, особенно затрагивающие пограничные реки и прилегающие земли.\n 6) Санитарно-эпидемиологическая обстановка — эпидемии, эпизоотии, эпифитотии, угрозы и меры предотвращения.\n 7) Индустриальные проекты (арктическое/антарктическое направление).\n 8) Индустриальные проекты в приграничных районах — заводы, производства, технопарки, новые технологии.\n 9) Инфраструктурные проекты в приграничных районах — дороги, мосты, транспорт, логистика.\n 10) Культура малочисленных народностей (нанайцы, монголы, уйгуры, нанайцы и хэчжэ) — политика, традиции, бытовая жизнь нанайцев, монголов, уйгуров, и хэчжэ (малочисленных народов).\n\n Отметь только те темы которым статья действительно соответствует.\n\n -------------------------------------\n 5. Формат ответа\n Вернуть строго JSON без пояснений и дополнительных слов\n {\n \"translation_text\" \"<дословный и точный перевод текста на русский язык статьи без сокращений>\",\n \"short_text\" \"<пересказ переведённого текста>\",\n \"title\" \"<краткая суть новости (1–2 предложения)>\",\n \"category\" \"<названий категорий которым соответствует статья>\"\n }\n Если статья не относится ни к одной теме или не привязана к нужным регионам — вернуть\n {\"translation_text\" \"\" \"short_text\" \"\" \"title\" \"\" \"category\" \"\"}" + } + ] +} \ No newline at end of file diff --git a/main.py b/main.py new file mode 100644 index 0000000..2fc98bd --- /dev/null +++ b/main.py @@ -0,0 +1,383 @@ +from fastapi import FastAPI, Request, BackgroundTasks, Query +from fastapi.middleware.cors import CORSMiddleware +from pydantic import BaseModel +import logging +import subprocess +import requests +from bs4 import BeautifulSoup +from urllib.parse import urljoin +import json +from datetime import datetime as dt +import uvicorn + +import time +from datetime import datetime + +import settings_work as sw +import work_parser as wp + +app = FastAPI(title="Parser API", + description="API для запуска парсинга в базу данных", + version="1.0") + +# Настройка логгера +logging.basicConfig(filename="app.log", level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s") +logger = logging.getLogger(__name__) + +@app.get("/logs") +def get_logs(): + with open("app.log", "r") as file: + lines = file.readlines()[-100:] # последние 100 строк + return {"logs": lines} + +# Инициализация таблицы статуса парсинга +wp.create_table() + +app.add_middleware( + CORSMiddleware, + allow_origins=["*"], # или список разрешенных адресов, например ["http://localhost:8080"] + allow_credentials=True, + allow_methods=["*"], + allow_headers=["*"], +) + + +PROXIES_URL = "https://raw.githubusercontent.com/TheSpeedX/SOCKS-List/master/http.txt" + + +def download_proxies(url): + response = requests.get(url) + if response.status_code == 200: + proxies = response.text.splitlines() # список прокси по строкам + return proxies + else: + return [] + + +def fetch_with_proxy(url, proxy, verify, timeout): + proxies = { + 'http': f'http://{proxy}', # или 'socks5://' если SOCKS5 и т.п. + 'https': f'http://{proxy}', + } + try: + response = requests.get(url, proxies=proxies, timeout=timeout, verify=verify) + response.encoding = 'utf-8' + response.raise_for_status() + return response.text + except: + return None + + +# Общие функции нахождения ссылок +def extract_map_area_hrefs(url, verify=True, ist_number=1): + headers = { + "User-Agent": "Mozilla/5.0 (compatible; MyScraper/1.0; +https://example.com)" + } + + resp = requests.get(url, headers=headers, verify=verify) + + resp.raise_for_status() + + soup = BeautifulSoup(resp.text, "html.parser") + + hrefs = [] + if ist_number == 1: + for map_tag in soup.find_all("li", attrs={"data-page": "1"}): + for a in map_tag.find_all("a", href=True): + href = a["href"] + abs_url = urljoin(url, href) + print(abs_url) + hrefs.append(abs_url) + else: + for map_tag in soup.find_all("map"): + for area in map_tag.find_all("area", href=True): + href = area["href"] + abs_url = urljoin(url, href) + hrefs.append(abs_url) + return hrefs + +# функции парсера первого источника (газета) +def extract_text_from_url_one(url, timeout=10, verify=True): + + proxies_list = download_proxies(PROXIES_URL) + + response = "" + for proxy in proxies_list: + response = fetch_with_proxy(url, proxy=proxy, timeout=timeout, verify=verify) + if response: + break + else: + response = "" + + soup = BeautifulSoup(response, "html.parser") + + + title_div = soup.find('div', class_='newsdetatit') + title_text = '' + if title_div: + h3_tag = title_div.find('h3') + if h3_tag: + title_text = h3_tag.get_text(strip=True) + + content_div = soup.find('div', class_='newsdetatext') + content_text = '' + if content_div: + founder_content = content_div.find('founder-content') + if founder_content: + p_tags = founder_content.find_all('p') + content_text = '\n'.join(p.get_text(strip=True) for p in p_tags) + + text = title_text + content_text + + if len(text) > 4500: + text = text[:4500] + print(len(text)) + return text + +#Функции парсера второго источника (военного) +def extract_text_from_url(url, timeout=10, verify=True): + proxies_list = download_proxies(PROXIES_URL) + + response = "" + for proxy in proxies_list: + response = fetch_with_proxy(url, proxy=proxy, timeout=timeout, verify=verify) + if response: + break + else: + response = "" + + soup = BeautifulSoup(response, 'html.parser') + + # Находим контейнер div.whitecon.article + container = soup.find("div", class_="whitecon article") + if not container: + return "" + + # Получение заголовка