image_crawler/basalam.js

118 lines
3.2 KiB
JavaScript

// basalam.js
const fetch = require("node-fetch"); // نصب با: npm install node-fetch@2
// ساخت URL جستجوی Basalam
function buildUrl(q, from = 0, size =25) {
const base = "https://services.basalam.com/web/v1/search/product/search";
const params = new URLSearchParams({
from: String(from),
q: q,
dynamicFacets: "true",
size: String(size),
enableNavigations: "true",
adsImpressionDisable: "false",
grouped: "true"
});
return base + "?" + params.toString();
}
// استخراج آیتم‌ها از JSON پاسخ Basalam
function extractItems(json) {
const candidates = [
json?.data?.products,
json?.data?.items,
json?.products,
json?.items,
json?.hits,
json?.groups?.flatMap(g => g.items || g.products || []),
json?.dynamicFacets?.flatMap(f => f.items || [])
];
for (const c of candidates) {
if (Array.isArray(c) && c.length) return c;
}
return [];
}
// نگاشت هر آیتم به ساختار استاندارد
function mapItem(item) {
const title =
item.title ||
item.name ||
item.displayName ||
item.productName ||
item?.payload?.title ||
"بدون عنوان";
const image = [
item?.photo?.MEDIUM,
item?.photo?.SMALL,
item?.image_url,
item?.image,
item?.media?.[0]?.url,
item?.thumbnail,
Array.isArray(item?.images) ? item.images[0] : null
].find(src => typeof src === "string" && src.trim().length > 0) || "https://via.placeholder.com/150";
const price =
item.price ||
item.unitPrice ||
item?.payload?.price ||
item?.minPrice ||
(item.prices && item.prices.price);
const priceText =
price != null
? typeof price === "object"
? price.value || JSON.stringify(price)
: price
: "—";
const category = item?.categoryTitle || item?.category || "—";
return {
title,
category,
price: priceText,
image,
description:
item.description ||
item.summary ||
item.details ||
item.overview ||
item?.payload?.description ||
""
};
}
// تابع اصلی برای جستجوی Basalam
async function searchBasalam(query, size = 12) {
if (!query) return [];
const url = buildUrl(query, 0, size);
const headers = {
accept: "application/json, text/plain, */*",
"accept-language": "en-US,en;q=0.9,fa;q=0.8",
"x-client-info": JSON.stringify({
version: "3.38.7",
project: "charsou",
name: "web.public",
platform: "web",
deviceId: "0e238114-80e2-47b4-89d6-2173f7db9b54",
sessionId: "da951b95-26f2-4b54-bc17-6c82ec110d80"
})
};
try {
const resp = await fetch(url, { headers });
const json = await resp.json();
const items = extractItems(json).map(mapItem);
return items;
} catch (err) {
console.error("Basalam search error:", err);
return [];
}
}
// export تابع
module.exports = { searchBasalam };