initial commit

This commit is contained in:
dvirlabs 2025-06-17 02:04:03 +03:00
commit be92c28c55
6 changed files with 122 additions and 0 deletions

6
content.js Normal file
View File

@ -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 });
}
});

9
icon.svg Normal file
View File

@ -0,0 +1,9 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="-11.5 -10.23174 23 20.46348">
<title>React Logo</title>
<circle cx="0" cy="0" r="2.05" fill="#61dafb"/>
<g stroke="#61dafb" stroke-width="1" fill="none">
<ellipse rx="11" ry="4.2"/>
<ellipse rx="11" ry="4.2" transform="rotate(60)"/>
<ellipse rx="11" ry="4.2" transform="rotate(120)"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 366 B

35
inject.js Normal file
View File

@ -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 }, '*');
})();
})();

24
manifest.json Normal file
View File

@ -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": ["<all_urls>"]
}
]
}

17
popup.html Normal file
View File

@ -0,0 +1,17 @@
<!DOCTYPE html>
<html>
<head>
<title>AliExpress Scraper</title>
<style>
body { font-family: sans-serif; padding: 10px; }
pre { max-height: 300px; overflow-y: auto; background: #f0f0f0; padding: 10px; }
button { margin-top: 10px; }
</style>
</head>
<body>
<h3>AliExpress Product JSON</h3>
<pre id="output">Loading...</pre>
<button id="copyBtn">Copy to Clipboard</button>
<script src="popup.js"></script>
</body>
</html>

31
popup.js Normal file
View File

@ -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);
}
});
});