commit be92c28c5552da0699114615d6a70d715e0f4022 Author: dvirlabs Date: Tue Jun 17 02:04:03 2025 +0300 initial commit diff --git a/content.js b/content.js new file mode 100644 index 0000000..e2b7fac --- /dev/null +++ b/content.js @@ -0,0 +1,6 @@ +window.addEventListener("message", (event) => { + if (event.source !== window) return; + if (event.data?.type === "FROM_INJECTED") { + chrome.runtime.sendMessage({ type: "PRODUCT_DATA", data: event.data.data }); + } +}); diff --git a/icon.svg b/icon.svg new file mode 100644 index 0000000..ea77a61 --- /dev/null +++ b/icon.svg @@ -0,0 +1,9 @@ + + React Logo + + + + + + + diff --git a/inject.js b/inject.js new file mode 100644 index 0000000..6b88537 --- /dev/null +++ b/inject.js @@ -0,0 +1,35 @@ +(function () { + const waitForRunParams = (timeout = 5000) => { + return new Promise((res) => { + const start = Date.now(); + const check = () => { + if (window.runParams && Object.keys(window.runParams).length > 0) { + return res(window.runParams); + } + if (Date.now() - start > timeout) return res(null); + requestAnimationFrame(check); + }; + check(); + }); + }; + + (async () => { + const runParams = await waitForRunParams(); + const result = { + title: document.querySelector('[data-pl="product-title"]')?.innerText || '', + images: runParams?.imageModule?.imagePathList || [], + specs: {}, + description: '' + }; + + const specsData = runParams?.specifications || runParams?.productInfoComponent?.specifications || []; + specsData.forEach(group => { + (group.attributes || []).forEach(attr => { + result.specs[attr.attrName] = attr.attrValue; + }); + }); + + // שלח חזרה לתוסף + window.postMessage({ type: 'FROM_INJECTED', data: result }, '*'); + })(); +})(); diff --git a/manifest.json b/manifest.json new file mode 100644 index 0000000..cbad36c --- /dev/null +++ b/manifest.json @@ -0,0 +1,24 @@ +{ + "manifest_version": 3, + "name": "AliExpress Scraper", + "version": "1.0", + "description": "Extract product data from AliExpress into JSON.", + "permissions": ["scripting", "activeTab"], + "action": { + "default_popup": "popup.html", + "default_icon": "icon.svg" + }, + "content_scripts": [ + { + "matches": ["*://*.aliexpress.com/item/*"], + "js": ["content.js"] + } + ], + "host_permissions": ["*://*.aliexpress.com/*"], + "web_accessible_resources": [ + { + "resources": ["inject.js"], + "matches": [""] + } + ] +} diff --git a/popup.html b/popup.html new file mode 100644 index 0000000..2c9097a --- /dev/null +++ b/popup.html @@ -0,0 +1,17 @@ + + + + AliExpress Scraper + + + +

AliExpress Product JSON

+
Loading...
+ + + + diff --git a/popup.js b/popup.js new file mode 100644 index 0000000..1a55dd1 --- /dev/null +++ b/popup.js @@ -0,0 +1,31 @@ +document.addEventListener("DOMContentLoaded", async () => { + const [tab] = await chrome.tabs.query({ active: true, currentWindow: true }); + + // Inject inject.js into page + chrome.scripting.executeScript({ + target: { tabId: tab.id }, + func: () => { + const script = document.createElement("script"); + script.src = chrome.runtime.getURL("inject.js"); + document.documentElement.appendChild(script); + script.remove(); + } + }); + + // Wait for content.js to relay message from injected script + chrome.runtime.onMessage.addListener(function listener(message) { + if (message?.type === "PRODUCT_DATA") { + const data = message.data; + + const output = document.getElementById("output"); + output.textContent = JSON.stringify(data, null, 2); + + document.getElementById("copyBtn").onclick = () => { + navigator.clipboard.writeText(output.textContent); + alert("Copied!"); + }; + + chrome.runtime.onMessage.removeListener(listener); + } + }); +});