парсинг страницы происходит, ошибка при отправке запроса на нейронку, нужно разбираться, возможно из за величины текста или частые запросы
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
2026-04-09 15:56:09 +10:00
parent f4791491ef
commit 5d724a7a8d
2 changed files with 91 additions and 45 deletions

113
main.py
View File

@@ -9,7 +9,6 @@ from datetime import datetime, timedelta
import random
import zipfile
# from rarfile import RarFile
import tempfile
# Сторонние библиотеки (third-party)
@@ -17,17 +16,18 @@ from apscheduler.schedulers.asyncio import AsyncIOScheduler
from bs4 import BeautifulSoup
from contextlib import asynccontextmanager
from docx import Document
from newspaper import Article
from fastapi import BackgroundTasks, FastAPI, Query, Request, Depends
from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import FileResponse
from pydantic import BaseModel
from urllib.parse import urljoin
from pydantic import BaseModel, HttpUrl
from urllib.parse import urljoin, urlparse, urldefrag
import uvicorn
import requests
# Локальные импорты
import settings_work as sw
# import settings_work as sw
import work_parser as wp
DOCUMENTS_DIR = os.path.join(os.path.dirname(os.path.abspath(__file__)), "documents")
@@ -206,21 +206,9 @@ def extract_text_from_url(url, timeout=10, verify=True):
return "\n".join(content_text), time_t
# Общий запрос на GPT
def gpt_response_message(content, ist_number=1):
def gpt_response_message(content: str, name_promt: str):
# Promts = sw.read_settings().sources
# if ist_number == 1:
# contentGPT = Promts[0].prompt.replace('{content}', content)
# else:
# contentGPT = Promts[1].prompt.replace('{content}', content)
if ist_number == 1:
url_ist = "http://epaper.hljnews.cn/hljrb/pc/layout"
else:
url_ist = "https://def.ltn.com.tw/breakingnewslist"
contentGPT = wp.get_promt(url_ist).replace('{content}', content)
contentGPT = wp.get_promt(name_promt).replace('{content}', content)
url = 'http://45.129.78.228:8484' #10.8.0.14:5500
params = {'text': contentGPT}
@@ -242,15 +230,6 @@ def gpt_response_message(content, ist_number=1):
logger.info(f"Привышен лимит запросов {max_retries}")
return ""
# перезапуск сервиса GPT при неудачных попытках запроса
# def restart_service(service_name):
# try:
# subprocess.run(['sudo', 'systemctl', 'restart', service_name], check=True)
# time.sleep(30)
# print(f"Сервис {service_name} успешно перезапущен")
# except subprocess.CalledProcessError:
# print(f"Не удалось перезапустить сервес {service_name}")
# Общие функции проверки ссылок
def check_url(url):
print(url)
@@ -342,7 +321,6 @@ def start_pars_one_istochnik(data_init=""):
for page_number in range(1, 9):
url = f'http://epaper.hljnews.cn/hljrb/pc/layout/{current_year}{current_month}/{current_day}/node_0{page_number}.html'
wp.update_task(task_id, status='in_progress', source_url=url, started_at=datetime.utcnow())
print(f"Сбор href из: {url}")
@@ -358,7 +336,7 @@ def start_pars_one_istochnik(data_init=""):
print(f"Страница {page_number} [{i}/{len(hrefs)}] parsing {link}")
text = extract_text_from_url_one(link)
if len(text) >= 100:
response_text = gpt_response_message(text, ist_number=2)
response_text = gpt_response_message(text, url_ist = "http://epaper.hljnews.cn/hljrb/pc/layout")
print(response_text)
if response_text:
update_bd_and_create_document(response_text=response_text, article_date=f"{current_year}/{current_month}/{current_day}", url=link, parsed_at=str(dt.now()), original_text=text, other=url)
@@ -386,7 +364,7 @@ def start_pars_two_istochnik():
try:
text, time_text = extract_text_from_url(hrefs)
if len(text) >= 100:
response_text = gpt_response_message(text)
response_text = gpt_response_message(text, url_ist = "https://def.ltn.com.tw/breakingnewslist")
print(response_text)
if response_text:
update_bd_and_create_document(response_text=response_text, article_date=time_text, url=hrefs, parsed_at=str(dt.now()), original_text=text, other=url)
@@ -395,6 +373,64 @@ def start_pars_two_istochnik():
wp.update_task(task_id, status='completed', finished_at=datetime.utcnow())
#Функции start любого источника
def start_pars_all_istochnik(url:str, promt:str):
task_id = wp.insert_task(status='queued', source_url=url)
try:
response = requests.get(url)
response.raise_for_status()
except requests.RequestException:
return set()
soup = BeautifulSoup(response.text, 'html.parser')
base_domain = urlparse(url).netloc
# links = set()
for a_tag in soup.find_all('a', href=True):
href = a_tag['href'].strip()
if not href or href.startswith('mailto:') or href.startswith('javascript:'):
continue
# Приведение к абсолютному URL и удаление якорей (#...)
abs_url = urljoin(url, href)
abs_url, _ = urldefrag(abs_url)
parsed = urlparse(abs_url)
# Фильтр: ссылка должна быть на тот же домен
if parsed.netloc != base_domain:
continue
# Фильтрация по ключевым словам (пример для новостных сайтов)
# path_lower = parsed.path.lower()
# if any(keyword in path_lower for keyword in ['/news/', 'article', '2023', '2024', '/blog/', '/post/']):
print(f"Парсинг {abs_url}")
try:
article = Article(abs_url)
article.download()
article.parse()
if len(article.text) > 200 and article.publish_date:
time_text = article.publish_date.strftime("%Y/%m/%d %H:%M:%S")
print("URL:", abs_url)
print("Заголовок:", article.title)
print("Дата публикации:", time_text)
print("Текст статьи:", article.text)
response_text = gpt_response_message(str(article.text), promt)
print(response_text)
if response_text:
update_bd_and_create_document(response_text=response_text, article_date=time_text, url=abs_url, parsed_at=str(dt.now()), original_text=article.text, other=url)
except Exception as e:
print(f"Ошибка при обработке статьи {abs_url}: {e}")
logger.info(f"Ошибка при обработке статьи {abs_url}: {e}")
continue # Продолжаем со следующей статьей
wp.update_task(task_id, status='completed', finished_at=datetime.utcnow())
# start_pars_all_istochnik("https://www.asahi.com", "japan")
# Функции для автоматического запуска
def scheduled_parser_1():
start_pars_one_istochnik()
@@ -406,16 +442,25 @@ class ParserOneRequest(BaseModel):
time: str
@app.post("/parser_1", summary="Запуск процесса парсинга первого источника")
async def process_data(data: ParserOneRequest, background_tasks: BackgroundTasks):
async def process_parser_one_ist(data: ParserOneRequest, background_tasks: BackgroundTasks):
istochnik = data.time.split("-")
background_tasks.add_task(start_pars_one_istochnik, istochnik)
background_tasks.add_task(start_pars_one_istochnik(istochnik))
return {"message": "Процесс парсинга 1 источника запущен"}
@app.post("/parser_2" , summary="Запуск процеса парсинга второго источника")
async def process_data_gpt(background_tasks: BackgroundTasks):
async def process_parser_two_ist(background_tasks: BackgroundTasks):
background_tasks.add_task(start_pars_two_istochnik)
return {"message": "Процесс парсинга 2 источника запущен"}
class Parserall(BaseModel):
url: HttpUrl
promt: str
@app.post("/parser_all" , summary="Запуск процеса парсинга любого источника")
async def process_parser_all_ist(url: Parserall, background_tasks: BackgroundTasks):
background_tasks.add_task(start_pars_all_istochnik(str(url.url), url.promt))
return {"message": "Процесс парсинга любого источника запущен"}
# GET метод для получения
@app.get("/get_tasks_offset", summary="Метод получения задач парсинга")
def get_tasks_offset(limit: int = Query(10, gt=0), offset: int = Query(0, ge=0)):
@@ -536,7 +581,7 @@ async def download_all(dates: DownloadRange, background_tasks: BackgroundTasks):
return response
@app.get("/logs")
@app.get("/logs", summary="Показать логи")
def get_logs():
with open("app.log", "r") as file:
lines = file.readlines()[-10:] # последние 10 строк