(20221228:该篇文章的代码已经过时。由于 manifest_version、createEvent 等的变化,可参阅我的另一篇文章。 )
感觉网上关于插件开发的文章不多,其实插件开发很简单,也很方便。比起 selenium 解析网页,用 javascript 代码直接嵌入浏览器要方便很多。本文介绍了一个简单的自动发弹幕的例子,其实用插件做爬虫也是可行的。插件本地存储可以用 localStorage 先把爬取的资源链接存好,然后做个页面用表格展示,表格另存到本地,再用 python 程序直接访问链接。
自动发弹幕这个例子只需要三个文件,manifest.json ,background.js ,Bw.png (插件图标)。
manifest.json 文件代码:
{
"manifest_version": 2,
"name": "弹幕助手",
"description": "自动填充弹幕",
"version": "1.0",
"permissions": [
"tabs", "https://secure.flickr.com/"
],
"background": {
"scripts": ["background.js"]
},
"browser_action": {
"default_title": "自动填充弹幕",
"default_icon": "Bw.png"
}
}
background.js 文件代码:
// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Called when the user clicks on the browser action.
var sleep = function(time) {
var startTime = new Date().getTime() + parseInt(time, 10);
while(new Date().getTime() < startTime) {}
};
function checkURL(url){
console.log('URL:'+url);
var flag = false;
if(typeof url == "undefined" || null == url)
url = window.location.href;
// var regex = /.*\:\/\/.*\/form.php/;
var regex = /https\:\/\/.*bilibili\.com.*/;
var match = url.match(regex);
if(typeof match != "undefined" && null != match)
flag = true;
return flag;
}
function autoAddValue()
{
chrome.tabs.executeScript(null,
// 直接修改 input 的 value 值可能会引发问题。因为浏览器会认为程序自动输入的值是输入框的默认值,认为用户并没有输入文字!
{code:" var input = document.querySelectorAll('input.bilibili-player-video-danmaku-input')[0]; \
var playbutton = document.querySelectorAll('div.bilibili-player-video-state')[0];\
var ClickDiv = document.querySelectorAll('div.bilibili-player-video-btn-send')[0]; \
\
function fireClick(node){ \
if (document.createEvent) {\
var evt_m = document.createEvent('MouseEvents');\
evt_m.initMouseEvent('click', true, false);\
node.dispatchEvent(evt_m); \
} else if(document.createEventObject) {\
node.fireEvent('onclick') ; \
} else if (typeof node.onclick == 'function') {\
node.onclick(); \
}\
}\
function inputValue(dom, st) {\
var evt = new InputEvent('input', {\
inputType: 'insertText',\
data: st,\
dataTransfer: null,\
isComposing: false\
});\
dom.value = st;\
dom.dispatchEvent(evt);\
}\
\
fireClick(playbutton);\
inputValue(input, '这个视频我看了好多遍了,讲得好。');\
function bullet(){\
setInterval(function(){ \
fireClick(ClickDiv); \
console.log(\"点击一下\");\
}, 9000);\
}\
setTimeout(\"bullet()\", 5000 );\
"});
}
var countUpdate = 1;
chrome.browserAction.onClicked.addListener(function(tabId,changeInfo,tab){
countUpdate = 1;
});
chrome.tabs.onCreated.addListener(function(tabId,changeInfo,tab){
if(checkURL(tab.url)){
countUpdate = 1;
}
})
chrome.tabs.onUpdated.addListener( function(tabId,changeInfo,tab){
if(countUpdate==2){
sleep(5000);
if(checkURL(tab.url))
{
autoAddValue();
chrome.tabs.executeScript({
code: 'document.body.style.backgroundColor="#f2d649";console.log('+countUpdate.toString()+');' // 黄色
});
}
else
{
console.log('不是bilibili网站!'); // 这个无法显示在页面上,因为不是同一个页面。
chrome.tabs.executeScript({
code: 'document.body.style.backgroundColor="#f24182"' // 红色
});
}
}
countUpdate = countUpdate + 1;
});
// https://www.bilibili.com/video/BV1Ht411y73G?p=4
background.js 就是从浏览器启动一直在后台运行的东西。这个文件的功能是,如果网页是B站播放页面就把背景改为黄色,否则红色。在弹幕输入框输入“这视频很好.....”这句话,然后每9s发送一次。注意,输入文本和点击都必须发送事件,input 直接修改 value 属性是没用的。
把三个文件放在一个文件夹下,打开浏览器扩展页的开发者模式,把文件夹拖入扩展页,安装完成。
如果想了解插件还有什么其他的能力,访问 Chrome插件(Extensions)开发攻略 。