chrome插件开发(一)
注:本文章中所有内容仅供学习交流,不可用于任何商业用途和非法用途,否则后果自负,如有侵权,请联系作者立即删除!
有时候我们会遇到开发好的爬虫需要通过表单传递变量来进行测试的场景,但一条条复制信息然后上传测试实在太麻烦了,于是我找了找市面上的一些自动填写表单的插件。
遗憾的是,一路用下来基本上都是要收费的,作为勤勤恳恳的牛马,那必不可能为了公司花自己的钱。于是我打算摸索着自己开发一款针对我那个测试网站的自动填写表单插件。就当作是入门一下chrome插件开发了。
一、基础知识
官方文档
首先还是介绍一下我从各类网站以及ai上提炼总结的有关chrome插件开发的基础知识。
一款chrome插件最重要的一个文件就是manifest.json了,这个文件里面包含了这款插件所有的配置信息,包括版本号、名称、权限、使用的html、css、js等。
{"manifest_version": 3,"name": "Example.com Auto-Filler","version": "1.0","description": "Automatically fills form fields on example.com","permissions": ["activeTab", "scripting"],"action": {"default_icon": {"16": "icon16.png","48": "icon48.png","128": "icon128.png"},"default_title": "Example.com Auto-Filler","default_popup": "popup.html"},"content_scripts": [{"matches": ["http://www.example.com/*", "https://www.example.com/*"],"js": ["content.js"],"run_at": "document_end"}],"icons": {"16": "icon16.png","48": "icon48.png","128": "icon128.png"}
}
以上述信息为例,manifest_version是版本号,基本上固定为3,也有2的,但是比较适用于老版本浏览器
- name是这款插件的名字,可以随意修改
- version是这款插件的版本号,最新开发就填1.0,小改动就1.1,1.2这样更新,大改动就变2.0这种,也是自己修改的,方便区分
- description是插件描述,随意填
- permissions是插件的权限,例子里面activeTab表示获取到目标网页的使用权限,scripting表示可以通过插件将js或css注入网站,还有更多的一些权限自行参考官方文档
- action控制的是工具栏中的扩展程序图标,通俗来讲就是安装了插件后,我们可以在浏览器右上角点开插件看到这个插件的图标等信息
- content_scripts用于指定每次打开网页时使用符合特定网址格式的静态加载js或css文件,官方文档介绍比我说的好https://developer.chrome.com/docs/extensions/reference/manifest/content-scripts?hl=zh-cn
- icons就是插件的图标
二、开发
根据配置文件,我们需要在一个文件夹里面建立popup.html、content.js、icon16.png、icon48.png、icon128.png等文件
在这之前,我用ai生成了一个静态页面以用来测试我这个表单填写功能
<!DOCTYPE html>
<html lang="zh-CN">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>用户信息登记表单</title><style>* {box-sizing: border-box;margin: 0;padding: 0;font-family: 'Segoe UI', 'Microsoft YaHei', sans-serif;}body {background: linear-gradient(135deg, #6a11cb 0%, #2575fc 100%);min-height: 100vh;display: flex;justify-content: center;align-items: center;padding: 20px;}.container {width: 100%;max-width: 800px;background-color: #fff;border-radius: 20px;box-shadow: 0 15px 30px rgba(0, 0, 0, 0.2);overflow: hidden;}header {background: linear-gradient(90deg, #3498db, #2c3e50);color: white;padding: 30px 20px;text-align: center;}h1 {font-size: 2.5rem;margin-bottom: 10px;font-weight: 600;}.subtitle {font-size: 1.1rem;opacity: 0.9;}.form-container {padding: 30px;}.form-group {margin-bottom: 25px;}label {display: block;margin-bottom: 8px;font-weight: 500;color: #2c3e50;font-size: 1.1rem;}.required::after {content: " *";color: #e74c3c;}input, select, textarea {width: 100%;padding: 14px;border: 2px solid #e0e0e0;border-radius: 10px;font-size: 1rem;transition: all 0.3s ease;}input:focus, select:focus, textarea:focus {outline: none;border-color: #3498db;box-shadow: 0 0 0 3px rgba(52, 152, 219, 0.2);}.radio-group, .checkbox-group {display: flex;flex-wrap: wrap;gap: 15px;margin-top: 8px;}.radio-option, .checkbox-option {display: flex;align-items: center;gap: 8px;}.form-row {display: flex;gap: 20px;}.form-col {flex: 1;}button {background: linear-gradient(90deg, #3498db, #2c3e50);color: white;border: none;padding: 16px 40px;font-size: 1.1rem;border-radius: 50px;cursor: pointer;transition: all 0.3s ease;display: block;margin: 30px auto 10px;font-weight: 600;box-shadow: 0 4px 15px rgba(52, 152, 219, 0.3);}button:hover {transform: translateY(-3px);box-shadow: 0 7px 20px rgba(52, 152, 219, 0.4);background: linear-gradient(90deg, #2980b9, #1a252f);}button:active {transform: translateY(-1px);}.form-note {text-align: center;color: #7f8c8d;font-size: 0.9rem;margin-top: 10px;}footer {text-align: center;padding: 20px;background-color: #f8f9fa;color: #7f8c8d;font-size: 0.9rem;}/* 响应式设计 */@media (max-width: 768px) {.form-row {flex-direction: column;gap: 15px;}h1 {font-size: 2rem;}.form-container {padding: 20px;}}.input-with-icon {position: relative;}.input-with-icon i {position: absolute;left: 15px;top: 50%;transform: translateY(-50%);color: #7f8c8d;}.input-with-icon input {padding-left: 45px;}</style><link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/css/all.min.css">
</head>
<body><div class="container"><header><h1>用户信息登记表</h1><p class="subtitle">请填写以下信息以完成注册</p></header><div class="form-container"><form id="registrationForm"><div class="form-row"><div class="form-col"><div class="form-group"><label for="fullName" class="required">姓名</label><div class="input-with-icon"><i class="fas fa-user"></i><input type="text" id="fullName" name="fullName" required placeholder="请输入您的真实姓名"></div></div></div><div class="form-col"><div class="form-group"><label for="phone" class="required">手机号码</label><div class="input-with-icon"><i class="fas fa-phone"></i><input type="tel" id="phone" name="phone" required placeholder="请输入11位手机号码"></div></div></div></div><div class="form-row"><div class="form-col"><div class="form-group"><label for="email" class="required">电子邮箱</label><div class="input-with-icon"><i class="fas fa-envelope"></i><input type="email" id="email" name="email" required placeholder="example@domain.com"></div></div></div><div class="form-col"><div class="form-group"><label for="birthdate">出生日期</label><div class="input-with-icon"><i class="fas fa-calendar"></i><input type="date" id="birthdate" name="birthdate"></div></div></div></div><div class="form-group"><label for="password" class="required">设置密码</label><div class="input-with-icon"><i class="fas fa-lock"></i><input type="password" id="password" name="password" required placeholder="至少8位字符"></div></div><div class="form-group"><label for="confirmPassword" class="required">确认密码</label><div class="input-with-icon"><i class="fas fa-lock"></i><input type="password" id="confirmPassword" name="confirmPassword" required placeholder="再次输入密码"></div></div><div class="form-group"><label>性别</label><div class="radio-group"><div class="radio-option"><input type="radio" id="male" name="gender" value="male" checked><label for="male">男</label></div><div class="radio-option"><input type="radio" id="female" name="gender" value="female"><label for="female">女</label></div><div class="radio-option"><input type="radio" id="other" name="gender" value="other"><label for="other">其他</label></div></div></div><div class="form-group"><label for="country">所在国家/地区</label><select id="country" name="country"><option value="">请选择国家/地区</option><option value="china" selected>中国</option><option value="usa">美国</option><option value="uk">英国</option><option value="japan">日本</option><option value="korea">韩国</option><option value="others">其他国家</option></select></div><div class="form-group"><label for="interests">兴趣爱好(可多选)</label><div class="checkbox-group"><div class="checkbox-option"><input type="checkbox" id="reading" name="interests" value="reading"><label for="reading">阅读</label></div><div class="checkbox-option"><input type="checkbox" id="travel" name="interests" value="travel"><label for="travel">旅行</label></div><div class="checkbox-option"><input type="checkbox" id="sports" name="interests" value="sports"><label for="sports">运动</label></div><div class="checkbox-option"><input type="checkbox" id="music" name="interests" value="music"><label for="music">音乐</label></div><div class="checkbox-option"><input type="checkbox" id="tech" name="interests" value="tech"><label for="tech">科技</label></div></div></div><div class="form-group"><label for="bio">个人简介</label><textarea id="bio" name="bio" rows="4" placeholder="请简要描述您的个人经历、专业技能或兴趣爱好..."></textarea></div><button type="submit">提交注册</button><p class="form-note">带 <span class="required">*</span> 的为必填项</p></form></div><footer><p>© 2023 用户信息管理系统 | 隐私政策 | 使用条款</p></footer></div><script>document.getElementById('registrationForm').addEventListener('submit', function(e) {e.preventDefault();// 表单验证逻辑const fullName = document.getElementById('fullName').value;const password = document.getElementById('password').value;const confirmPassword = document.getElementById('confirmPassword').value;if (fullName.length < 2) {alert('请输入有效的姓名');return;}if (password.length < 8) {alert('密码长度至少为8个字符');return;}if (password !== confirmPassword) {alert('两次输入的密码不一致');return;}// 验证通过后的处理alert('表单提交成功!感谢您的注册。');// 在实际应用中,这里可以添加AJAX请求将数据发送到服务器this.reset();});</script>
</body>
</html>
(ps:不得不说现在ai能力真强,这页面可比刚毕业时我写的那个好看多了)
2.1 content.js
content.js里面主要就是写自动填写表单的函数了,首先我们要关注到表单中基本都是靠input输入框来填写表单,然后有几个是通过select来选择的
当然还有可能遇到下拉框的情况
function autoFillInput() {// 主要应对文本框填写const fields = [{selector: 'input[id="fullName"]', value: '张三'},{selector: 'input[id="phone"]', value: '13555555555'},{selector: 'input[id="email"]', value: 'aaa@aaa.cpm'},{selector: 'input[id="birthdate"]', value: '2002-03-25'},{selector: 'input[id="password"]', value: '12345678'},{selector: 'input[id="confirmPassword"]', value: '12345678'},{selector: 'select[id="country"]', value: "usa"} // 下拉框填写略微特殊]for (let field of fields) {const element = document.querySelector(field.selector);if (element) {element.value = field.value;}}
}function autoFillLabel() {// 主要应对选项框填写const fields = [{selector: 'input[name="gender"]', value: '其他'},{selector: 'input[name="interests"]', value: '运动'},]for (let field of fields) {const elements = document.querySelectorAll(field.selector);for (let element of elements) {const parent = element.parentNodeconst label = parent.querySelector('label');if (label.innerText === field.value) {element.focus();element.dispatchEvent(new MouseEvent('click'))}}}
}// 延迟启动填表函数,等待页面加载成功
setTimeout(autoFillInput, 1000);
setTimeout(autoFillLabel, 2000);
其实里面就是一些很基础的js,按照这个代码写好函数后,打开测试页面就会发现,短暂延迟后表单成功填写