我正在尝试创建一个 Google Chrome 扩展程序网络抓取工具,其想法是用户单击图标,扩展程序会抓取当前活动选项卡并将一些处理后的数据打印到弹出窗口中。
为此,我决定在清单中设置默认的 popup.html,并将 popup.js sendMessage 到 content.js 文件,其中包含抓取网页的函数。但是,在我的实现过程中,我在 popup.html:0 -> Unchecked runtime.lastError: Could not建立连接上收到以下错误。接收端不存在。
我尝试在线查找我的确切问题,发现一个已经存在的堆栈溢出页面:Chrome扩展消息传递:未检查的runtime.lastError:无法建立连接。接收端不存在
但是,我尝试实现此操作,但错误仍然存在。我在下面附上了我的manifest.JSON、popup.html、popup.js、content.js 和background.js 文件:
清单.JSON
{
"manifest_version": 3,
"name": "HTML Scraper",
"version": "1.0",
"description": "Scrapes the HTML of the current webpage and prints it to console.",
"permissions": ["storage", "activeTab", "scripting"],
"background": {
"service_worker": "background.js",
"type": "module"
},
"action": {
"default_popup": "popup.html",
"default_icon": "icons/icon16.png"
},
"icons": {
"16": "icons/icon16.png",
"48": "icons/icon48.png",
"128": "icons/icon128.png"
}
}
popup.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Popup</title>
<!-- Include popup.js -->
<script src="popup.js"></script>
</head>
<body>
<h1>Hi!</h1>
</body>
</html>
popup.js
if (document.readyState != 'loading') {
chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
chrome.tabs.sendMessage(tabs[0].id, {action: 'scrapeHTML'}, function(response) {
console.log('Scrape command sent to content script');
});
});
} else {
document.addEventListener('DOMContentLoaded', function() {
chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
chrome.tabs.sendMessage(tabs[0].id, {action: 'scrapeHTML'}, function(response) {
console.log('Scrape command sent to content script');
});
console.log("tester");
});
});
}
内容.js
function ScrapeHTML() {
const htmlcontent = document.body.innerText;
const url = document.location.href;
const containsAmazon = url.includes("amazon.com/");
chrome.runtime.sendMessage({action: 'sentLoad'},{
html: htmlcontent,
containsAmazon: containsAmazon
});
}
document.addEventListener('DOMContentLoaded', function() {
chrome.runtime.onMessage.addListener(function(message, sender, sendResponse) {
if (message.action == 'scrapeHTML') {
ScrapeHTML();
} else {
console.log('Unknown message received from popup script:', message);
}
});
});
背景.js
// background.js
import {amazonMessage} from './helpers.js';
chrome.runtime.onMessage.addListener((message) => {
if (message.action === 'sentLoad') {
const containsAmazon = message.containsAmazon;
const text = message.html;
if (containsAmazon) {
console.log(amazonMessage(text, "Sponsored", "Products related to this item"));
} else {
console.log(text);
}
chrome.storage.local.set({counter: text}, function() {
console.log("Message saved to local storage.");
});
}
});
您需要在manifest.json中声明
content_scripts
,然后在Chrome中重新加载/安装扩展程序后重新注入content_scripts
,但更简单的解决方案是通过chrome.scripting.executeScript
而不是content_scripts +消息传递使用编程注入,请参阅这些示例。
popup.html:添加
defer
以在 DOMContentLoaded: 处加载脚本
<script src="popup.js" defer></script>
popup.js:
(async () => {
const [tab] = await chrome.tabs.query({active: true, currentWindow: true});
const [{result}] = await chrome.scripting.executeScript({
target: {tabId: tab.id},
func: () => document.body.innerText,
});
document.body.textContent = new URL(tab.url).hostname + ': ' +
result.slice(0, 100) + '...';
})();
不需要后台脚本或单独的内容脚本来进行如此简单的抓取。