-
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathpdp_scraper.js
More file actions
134 lines (113 loc) · 3.9 KB
/
pdp_scraper.js
File metadata and controls
134 lines (113 loc) · 3.9 KB
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
134
(async function() {
const CONFIG = window.PDP_CONFIG;
if (!CONFIG) {
console.error("PDP Config not found!");
return;
}
// --- HELPER: TUNGGU ELEMEN MUNCUL ---
// Fungsi ini akan mengecek keberadaan elemen setiap 500ms
// sampai elemen ditemukan atau timeout (default 10 detik)
function waitForSelector(selector, timeout = 10000) {
return new Promise((resolve, reject) => {
// Jika elemen sudah ada, langsung resolve
if (document.querySelector(selector)) {
return resolve(document.querySelector(selector));
}
const observer = new MutationObserver(() => {
if (document.querySelector(selector)) {
observer.disconnect();
resolve(document.querySelector(selector));
}
});
observer.observe(document.body, {
childList: true,
subtree: true
});
// Timeout safety agar tidak hang selamanya
setTimeout(() => {
observer.disconnect();
reject(new Error(`Timeout waiting for selector: ${selector}`));
}, timeout);
});
}
// --- FUNGSI SCRAPING UTAMA ---
function scrapePDP() {
const sel = CONFIG.selectors;
const details = {
fullName: "",
description: "",
price: "",
stock: "",
rating: "",
sold: "",
images: [],
shopName: "",
shopLocation: ""
};
// 1. Nama Lengkap Produk
const nameEl = document.querySelector(sel.productName);
if (nameEl) details.fullName = nameEl.innerText;
// 2. Deskripsi
const descEl = document.querySelector(sel.description);
if (descEl) {
let text = descEl.innerText;
if (text.length > 500) text = text.substring(0, 500) + "... (Lihat selengkapnya di web)";
details.description = text;
}
// 3. Harga Detail
const priceEl = document.querySelector(sel.price);
if (priceEl) details.price = priceEl.innerText;
// 4. Stok
const stockEl = document.querySelector(sel.stock);
if (stockEl) {
details.stock = stockEl.innerText.replace(/Stok:\s*/i, '').trim();
}
// 5. Gambar
const imgEls = document.querySelectorAll(sel.images);
imgEls.forEach(img => {
// Filter gambar yang valid
if (img.src && !img.src.startsWith('data:image/svg') && img.src.includes('http')) {
details.images.push(img.src);
}
});
// 6. Rating & Terjual
const ratingEl = document.querySelector(sel.rating);
if (ratingEl) details.rating = ratingEl.innerText;
const soldEl = document.querySelector(sel.sold);
if (soldEl) details.sold = soldEl.innerText.replace('Terjual', '').trim();
// 7. Info Toko & Lokasi
const shopEl = document.querySelector(sel.shopName);
if (shopEl) details.shopName = shopEl.innerText;
const shipmentDiv = document.querySelector(sel.shipmentContainer);
if (shipmentDiv) {
const cityBold = shipmentDiv.querySelector('b');
if (cityBold) details.shopLocation = cityBold.innerText;
}
return details;
}
// --- EKSEKUSI ---
try {
// KITA TUNGGU DULU SAMPAI JUDUL PRODUK MUNCUL
// Ini adalah indikator bahwa React sudah selesai render konten utama
console.log("Menunggu render halaman detail...");
await waitForSelector(CONFIG.selectors.productName);
// Beri jeda ekstra 1 detik untuk gambar & elemen lain memuat sempurna
await new Promise(r => setTimeout(r, 1000));
console.log("Halaman siap, mulai scraping detail...");
const result = scrapePDP();
// Kirim pesan balik
chrome.runtime.sendMessage({
action: "pdp_scraped",
url: window.location.href,
data: result
});
} catch (error) {
console.error("Gagal Scrape Detail:", error);
// Opsional: Kirim pesan error ke sidepanel agar user tahu
chrome.runtime.sendMessage({
action: "pdp_scraped",
url: window.location.href,
data: { description: "Gagal mengambil data: Timeout atau Layout berubah." }
});
}
})();