题记- 就特么一个功能,自动根据区域填亚马逊邮编地址,马德,这一定是重复搞轮子。
做过亚马逊的都知道,因为session 有时间期限,或者某些站点没有经常使用,所以经常浏览页面的时候因为邮编不对,需要切换,不切换一定会有个问题,就是页面展现不全。另外,加亚马逊在中国的服务器实在是慢,手动切换确实没必要。
我也不知道市场上有无类似的插件。搜了几个关键词,没有找到,毕竟这东西没啥商业价值。秉着void 刚下载想测试下的想法,我就是试试自己开发一个插件吧,也许以后一发不可收拾,然后获得vc, 然后梦醒了。
这个插件的名字叫做Auto ZIP Code Setter ,别问我,Gemini 取得。
从来没有开发过chrome 插件,注册的时候才发现成为开发者还需要交5美金,靠,一想5美金心痛,虽然我一定会薅回来。所以就着vibe coding 的思路开始开发。
思路也很简单它无非就是js操作。后台测试了conselo,基本上确认可以实现,就开始使用void(感谢马斯克慷慨的grok api计划,150美金根本用不完),然后自己稍微review了代码。大概30分钟就出来了demo,靠,这比flask 容易多了。
然后我智慧的做了了个icon,发布反而很麻烦,设计权限,远程代码检测,图片等。这个以后再说,不过我的权限要求非常低,审核4个小时就过了。
以下是js 代码
console.log("Auto ZIP Code content script loaded. v1.3");
const targetConfigs = {
"www.amazon.com": {
openModalSelector: "#nav-global-location-popover-link, #glow-ingress-block",
zipInputInModalSelector: "#GLUXZipUpdateInput",
submitModalSelector: "#GLUXZipUpdate .a-button-input, input[aria-labelledby='GLUXZipUpdate-announce']",
zipCode: "95001",
currentLocationDisplaySelector: "#glow-ingress-line2",
expectedLocationText: "95001"
},
"www.amazon.co.uk": {
openModalSelector: "#nav-global-location-popover-link, #glow-ingress-block",
zipInputInModalSelector: "#GLUXZipUpdateInput",
submitModalSelector: "#GLUXZipUpdate .a-button-input, input[aria-labelledby='GLUXZipUpdate-announce']",
zipCode: "LS14 5ED",
currentLocationDisplaySelector: "#glow-ingress-line2",
expectedLocationText: "LS14 5ED"
},
"www.amazon.fr": {
openModalSelector: "#nav-global-location-popover-link, #glow-ingress-block",
zipInputInModalSelector: "#GLUXZipUpdateInput",
submitModalSelector: "#GLUXZipUpdate .a-button-input, input[aria-labelledby='GLUXZipUpdate-announce']",
zipCode: "75000",
currentLocationDisplaySelector: "#glow-ingress-line2",
expectedLocationText: "75000"
},
"www.amazon.es": {
openModalSelector: "#nav-global-location-popover-link, #glow-ingress-block",
zipInputInModalSelector: "#GLUXZipUpdateInput",
submitModalSelector: "#GLUXZipUpdate .a-button-input, input[aria-labelledby='GLUXZipUpdate-announce']",
zipCode: "23001",
currentLocationDisplaySelector: "#glow-ingress-line2",
expectedLocationText: "23001"
},
"www.amazon.de": {
openModalSelector: "#nav-global-location-popover-link, #glow-ingress-block",
zipInputInModalSelector: "#GLUXZipUpdateInput",
submitModalSelector: "#GLUXZipUpdate .a-button-input, input[aria-labelledby='GLUXZipUpdate-announce']",
zipCode: "10178",
currentLocationDisplaySelector: "#glow-ingress-line2",
expectedLocationText: "10178"
},
"www.amazon.it": {
openModalSelector: "#nav-global-location-popover-link, #glow-ingress-block",
zipInputInModalSelector: "#GLUXZipUpdateInput",
submitModalSelector: "#GLUXZipUpdate .a-button-input, input[aria-labelledby='GLUXZipUpdate-announce']",
zipCode: "07100",
currentLocationDisplaySelector: "#glow-ingress-line2",
expectedLocationText: "07100"
}
};
const currentHostname = window.location.hostname;
const config = targetConfigs[currentHostname];
function log(message) {
console.log(`[AutoZIP Extension]: ${message}`);
}
async function delay(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
async function waitForElement(selectorString, timeout = 10000) {
const startTime = Date.now();
log(`Waiting for element(s): ${selectorString} on ${currentHostname}`);
const selectors = selectorString.split(',').map(s => s.trim()).filter(s => s);
while (Date.now() - startTime < timeout) {
for (const selector of selectors) {
const element = document.querySelector(selector);
if (element && (element.offsetParent !== null || window.getComputedStyle(element).display !== 'none')) {
log(`Element found: ${selector}`);
return element;
}
}
await delay(500);
}
log(`Element(s) NOT FOUND after ${timeout}ms: ${selectorString}`);
return null;
}
async function executeLocationChange() {
if (!config) {
log("No configuration found for this site: " + currentHostname);
return;
}
log(`Starting location change process for: ${currentHostname} with ZIP/Postcode: ${config.zipCode}`);
if (config.currentLocationDisplaySelector && config.expectedLocationText) {
const locationDisplayElement = await waitForElement(config.currentLocationDisplaySelector, 3000);
if (locationDisplayElement && locationDisplayElement.textContent.includes(config.expectedLocationText)) {
log(`Location already set to include "${config.expectedLocationText}". No action needed.`);
return;
}
log("Current location does not match expected, or display element not found initially. Proceeding with update.");
}
const openModalButton = await waitForElement(config.openModalSelector);
if (!openModalButton) {
log("Could not find the button/link to open the location modal. Aborting.");
return;
}
log("Clicking to open location modal...");
openModalButton.click();
const zipInput = await waitForElement(config.zipInputInModalSelector, 15000);
if (!zipInput) {
log("ZIP/Postcode input field inside modal not found. Aborting.");
return;
}
log("ZIP/Postcode input field in modal found.");
zipInput.value = "";
await delay(100);
zipInput.value = config.zipCode;
log(`Set ZIP/Postcode input value to: ${config.zipCode}`);
zipInput.dispatchEvent(new Event('input', { bubbles: true, cancelable: true }));
zipInput.dispatchEvent(new Event('change', { bubbles: true, cancelable: true }));
zipInput.dispatchEvent(new Event('blur', { bubbles: true, cancelable: true }));
await delay(500);
const submitButton = await waitForElement(config.submitModalSelector);
if (!submitButton) {
log("Submit button inside modal not found. Aborting.");
return;
}
log("Clicking submit button in modal...");
submitButton.click();
log("Location change process has been attempted.");
if (config.currentLocationDisplaySelector && config.expectedLocationText) {
await delay(3000);
log("Attempting to verify location update...");
const updatedLocationDisplay = await waitForElement(config.currentLocationDisplaySelector, 7000);
if (updatedLocationDisplay && updatedLocationDisplay.textContent.includes(config.expectedLocationText)) {
log(`SUCCESS: Location display appears to be updated to include "${config.expectedLocationText}".`);
} else if (updatedLocationDisplay) {
log(`VERIFICATION: Location display text is now "${updatedLocationDisplay.textContent.trim()}". Manual check might be needed.`);
} else {
log("VERIFICATION: Could not find location display element after update attempt.");
}
}
}
if (document.readyState === "complete" || document.readyState === "interactive" || document.readyState === "loaded") {
log("Document ready, scheduling location change in 3 seconds...");
setTimeout(executeLocationChange, 3000);
} else {
log("Document not ready, adding DOMContentLoaded listener with 3s delay.");
window.addEventListener('DOMContentLoaded', () => {
log("DOMContentLoaded event fired, scheduling location change in 3 seconds...");
setTimeout(executeLocationChange, 3000);
});
}
comments (0)
please login to comment