Spaces:
Sleeping
Sleeping
File size: 5,115 Bytes
94c1837 b720cc9 94c1837 b720cc9 94c1837 b720cc9 94c1837 b720cc9 94c1837 b720cc9 94c1837 b720cc9 94c1837 b720cc9 94c1837 b7caa49 94c1837 eb7d8b7 94c1837 eb7d8b7 94c1837 b7caa49 94c1837 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 |
from bs4 import BeautifulSoup
from pathlib import Path
from fpdf import FPDF
from urllib.parse import urlparse
import openai
import time
import os
import logging
# ---------------- OPENAI ----------------
def init_openai(api_key: str):
openai.api_key = api_key
def clean_text_with_openai(raw_text: str) -> str:
"""
Bersihkan teks menggunakan OpenAI terbaru
- Hilangkan navigasi, footer, duplikasi
- Rangkum untuk customer service
- Pertahankan semua informasi penting, termasuk link website
"""
prompt = f"""
Tolong bersihkan dan ringkas teks berikut agar menjadi relevan untuk customer service:
- Hilangkan navigasi, footer, menu, iklan, dan duplikasi
- Pertahankan semua informasi penting, termasuk URL/link website, email, dan kontak resmi
- Rangkum secara rapi per section dengan judul yang jelas
- Hasil akhir tetap mudah dibaca dan lengkap untuk menjawab pertanyaan pengguna
Teks mentah:
{raw_text}
"""
response = openai.chat.completions.create(
model="gpt-4o-mini",
messages=[
{
"role": "system",
"content": (
"Kamu adalah asisten yang merapikan teks website agar siap digunakan dalam RAG chatbot berbasis FAISS.\n"
"Instruksi:\n"
"- Pisahkan konten menjadi bagian-bagian logis: Produk, Layanan, Testimoni, Kontak, Informasi Perusahaan, dsb.\n"
"- Hapus elemen navigasi, menu, footer, iklan, dan duplikasi.\n"
"- Jangan menghapus URL/link, email, atau informasi kontak resmi.\n"
"- Format teks supaya mudah dicari oleh vector database: paragraf pendek, bullet point untuk list, judul section.\n"
"- Jangan menambahkan opini, komentar, atau promosi tambahan.\n"
"- Tetap pertahankan semua informasi penting agar chatbot bisa menjawab pertanyaan pengguna dengan akurat.\n"
"- Output harus bersih, ringkas, lengkap, dan siap diindeks untuk retrieval."
)
},
{"role": "user", "content": prompt}
],
temperature=0
)
cleaned_text = response.choices[0].message.content.strip()
return cleaned_text
# ---------------- LOGGING ----------------
logging.basicConfig(
level=logging.INFO,
format="%(asctime)s [%(levelname)s] %(message)s",
datefmt="%Y-%m-%d %H:%M:%S"
)
# ---------------- SELENIUM ----------------
def init_driver(headless=True):
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.chrome.options import Options
from selenium import webdriver
options = Options()
if headless:
options.add_argument("--headless=new")
options.add_argument("--no-sandbox")
options.add_argument("--disable-dev-shm-usage")
options.add_argument("--disable-gpu")
options.binary_location = "/usr/bin/chromium" # path Chromium di HF Spaces
service = Service("/usr/bin/chromedriver") # pastikan path benar
driver = webdriver.Chrome(service=service, options=options)
logging.info("WebDriver berhasil diinisialisasi")
return driver
def init_driver_local(headless=True):
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
options = Options()
if headless:
options.add_argument("--headless")
options.add_argument("--disable-gpu")
options.add_argument("--no-sandbox")
options.add_argument("--window-size=1920,1080")
driver = webdriver.Chrome(options=options)
return driver
def fetch_page_text(driver, url: str) -> str:
logging.info("Mengambil halaman: %s", url)
driver.get(url)
time.sleep(2) # beri waktu agar JS selesai render
soup = BeautifulSoup(driver.page_source, "html.parser")
main_content = soup.find("main") or soup
text = main_content.get_text(separator="\n", strip=True)
logging.info("Halaman berhasil diambil (%d karakter)", len(text))
return text
# ---------------- PDF ----------------
def save_to_pdf(text: str, output_file: Path):
logging.info("Menyimpan teks ke PDF: %s", output_file)
pdf = FPDF()
pdf.set_auto_page_break(auto=True, margin=15)
pdf.add_page()
pdf.set_font("Arial", size=12)
for line in text.split("\n"):
if len(line) > 120:
chunks = [line[i:i+120] for i in range(0, len(line), 120)]
for chunk in chunks:
pdf.multi_cell(0, 6, chunk)
else:
pdf.multi_cell(0, 6, line)
pdf.ln(1)
pdf.output(str(output_file))
logging.info("PDF berhasil disimpan: %s", output_file)
def url_to_filename(url: str, folder: Path) -> Path:
parsed = urlparse(url)
path_safe = parsed.path.strip("/").replace("/", "_")
if path_safe:
safe_name = f"{parsed.netloc.replace('.', '_')}_{path_safe}.pdf"
else:
safe_name = f"{parsed.netloc.replace('.', '_')}.pdf"
output_file = folder / safe_name
logging.info("Nama file PDF untuk URL '%s': %s", url, output_file)
return output_file |