Список пользователей

1
Админ
Постов: 101
2
Элита
Постов: 34
3
Элита
Постов: 28
4
VIP
Постов: 26
5
Дизайнер
Постов: 25
6
Пользователи
Постов: 25
7
Пользователи
Постов: 24
8
Проверенные
Постов: 21

  • Страница 1 из 1
  • 1
Forum Updates - Парсер последних тем форума на главную V1
Дата: Вторник, 28.10.2025, 19:14 | Сообщение # 1 | | Написал: Начинающий
Автор темы
Мурчанн не в сети
        Сообщений:101
         Регистрация:20.10.2016

Скоро будет проведена серьёзная модернизация этого парсера.

Но прежде я публикую старую версию, которая тоже полностью работоспособна.

Она функционирует по другому принципу, выполняет более сложные операции и требует больше ресурсов.

Наша задача создать упрощённую версию, которая при этом будет работать очень быстро и без лагов.

Именно в этом и заключается гениальность.



Код
<style>
#custom-forum-cards {
display: flex;
flex-wrap: wrap;
gap: 20px;
justify-content: flex-start;
width: 100%;
}

.custom-card {
flex: 0 0 calc(25% - 15px); /* 4 карточки в ряд */
box-sizing: border-box;
border-radius: 2px;
overflow: hidden;
position: relative;

color: #fff;
cursor: pointer;
text-decoration: none;
background: linear-gradient(180deg, #1e1e1e 0%, #141414 100%);
}

.custom-card:hover {
transform: translateY(-1px) scale(1.02);
box-shadow: 0 12px 25px rgba(0, 0, 0, 0.5);
}

.custom-card-img {
width: 100%;
height: 170px;
overflow: hidden;
position: relative;
}

.custom-card-img img {
width: 100%;
height: 100%;
object-fit: cover;
transition: transform 0.5s ease;
}

.custom-card:hover .custom-card-img img {
transform: scale(1.08);
}

/* Заголовок */
.custom-card-title {
font-weight: 600;
font-size: 13px;
padding: 8px 10px 2px 10px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}

/* Короткое описание */
.custom-card-desc {
font-size: 11px;
color: #bbb;
padding: 0 10px 6px 10px;
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 12; /* меньше строк */
-webkit-box-orient: vertical;
white-space: normal;
opacity: 0.85;
}

/* Подпись/тема */
.custom-card-footer {
font-size: 10px;
text-transform: uppercase;
color: #999;
padding: 0 10px 10px 10px;
letter-spacing: 0.5px;
}

/* Бейдж */
.custom-card-badge {
position: absolute;
top: 10px;
left: 10px;
background: #000;
padding: 4px 8px;
border-radius: 6px;
font-size: 11px;
font-weight: bold;
text-transform: uppercase;
letter-spacing: 0.5px;
box-shadow: 0 0 10px rgba(133, 59, 151, 0.4);
}

/* Эффект затемнения */
.custom-card::after {
content: '';
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0);
transition: background-color 0.3s ease;
pointer-events: none;
}

.custom-card:hover::after {
background-color: rgba(0, 0, 0, 0.5);
}

</style>

<section class="sect flex-grow-1">
<div class="sect__header d-flex">
<h2 class="sect__title flex-grow-1"> Forum Updates</h2>
</div>

<div class="dark-border">

<div id="custom-forum-cards"></div>

<script>
(async function() {
const container = document.querySelector('#custom-forum-cards');
if (!container) return;

const forumListUrl = '/forum/0-0-1-34'; // URL раздела форума, откуда брать темы
const MAX_CARDS = 8;
const CACHE_KEY = 'forum_cards_cache';
const CACHE_TIME = 30 * 60 * 1000; // 30 минут

// Рендер карточек
function renderCards(cards) {
container.innerHTML = '';
cards.forEach(parsed => {
const title = parsed.title || 'Без названия';
const desc = parsed.text || '';
const img = parsed.img || '/forumimages/Newsletter-3.png';

// создаем обычную ссылку
const card = document.createElement('a');
card.className = 'custom-card';
card.href = parsed.href;
card.target = '_self'; // открывать в этой же вкладке
card.innerHTML = `
<div class="custom-card-img">
<img src="${img}" alt="${title}">
<div class="custom-card-badge">Новое</div>
</div>
<div class="custom-card-title">${title}</div>
<div class="custom-card-desc">${desc}</div>
`;
container.appendChild(card);
});
}

// Получение HTML страницы
async function fetchHTML(url) {
const res = await fetch(url);
return await res.text();
}

// Парсим список тем из форума
function parseThreadsFromList(html) {
const parser = new DOMParser();
const doc = parser.parseFromString(html, 'text/html');
const arr = [];
const items = doc.querySelectorAll('.threadNametd .threadLink');
for (let i = 0; i < items.length && arr.length < MAX_CARDS; i++) {
const a = items[i];
const titleEl = a.querySelector('.ipsType_pagetitle') || a;
const title = (titleEl && titleEl.textContent || '').trim();
let href = a.getAttribute('href') || a.href || '';
if (href && !href.startsWith('http')) {
href = window.location.origin + (href.startsWith('/') ? href : '/' + href);
}
if (href) arr.push({ href, title });
}
return arr;
}

// Парсим первое сообщение темы
function parseFirstPost(html) {
const parser = new DOMParser();
const doc = parser.parseFromString(html, 'text/html');
const post = doc.querySelector('.post_content, .post_body, .post, .ipsType_richText');
let text = '';
let img = '';
if (post) {
text = post.textContent.trim().substring(0, 89);
const imgEl = post.querySelector('img');
if (imgEl) {
img = imgEl.getAttribute('src') || '';
if (img && !img.startsWith('http')) {
const base = window.location.origin;
img = img.startsWith('/') ? (base + img) : (base + '/' + img);
}
}
}
return { text, img };
}

// Проверка кэша
const cached = localStorage.getItem(CACHE_KEY);
if (cached) {
const data = JSON.parse(cached);
const now = Date.now();
if (now - data.time < CACHE_TIME) {
renderCards(data.cards);
return;
}
}

// Основная логика
try {
const listHtml = await fetchHTML(forumListUrl);
const threads = parseThreadsFromList(listHtml);
const promises = threads.map(t =>
fetchHTML(t.href).then(html => ({ ...t, ...parseFirstPost(html) })).catch(() => null)
);
const results = (await Promise.all(promises)).filter(Boolean);

// сохраняем кэш
localStorage.setItem(CACHE_KEY, JSON.stringify({ time: Date.now(), cards: results }));

renderCards(results);
} catch (e) {
console.error('Ошибка:', e);
}
})();
</script>

</div>


Нет смысла подробно описывать функционал парсера сейчас — в крупном обновлении я представлю полное сравнение работы старой и новой версии.

Мурчанн

Признаюсь, не знаю почему, но глядя на звезды мне всегда хочется мечтать.
  • Страница 1 из 1
  • 1
Поиск: