浏览器插件开发爬虫记录

常用爬虫有各种各样的反爬限制,而如果是小数据量并且该网站反爬手段非常厉害的前提下,可以考虑使用浏览器插件作为爬虫手段

基本代码来源于这位博主分享的插件代码, 主要在他的基础上加了 请求代理、管理面板、脚本注入拦截到的请求数据和管理面板之间的交互

基本项目结构如下:
在这里插入图片描述

1 manifest.json

manifest.json 是浏览器加载插件、插件权限申请的配置文件

{"name": "xx爬虫",    // 插件名称"version": "1.0","manifest_version": 2,"browser_action": {"default_popup": "/html/popup/popup.html"    // 在浏览器上点击插件展示的页面内容},"permissions": [     // 权限申请,目前申请了代理、tab、存储等功能"proxy","tabs","storage","notifications"],"externally_connectable": {"matches": ["*://*.example.com/*"]
},"content_scripts": [    // 网页js注入管理程序{"matches": ["*://xxx.com/*"],"js": ["/js/content/page.js", "/js/content/install.js"],   // 注入哪些js"run_at": "document_start"    // 在哪个时间点注入}],"web_accessible_resources": ["/js/inject/pikazExcel.js","/js/inject/page.js","/js/inject/network.js"],"background": {    // 浏览器启动的时候,插件就在后台运行的js,是一个全局生命周期的存在"scripts": ["/js/background/background.js"],"persistent": false}
}
2 popup

popup可以理解为是一个插件的页面,可以通过页面上提供的方法调用插件里面的功能 如拦截到数据之后下载到本地, 或者请求后端接口拿代理ip进行代理,如果设置了代理,那么后续的请求都会走代理, 点击浏览器插件就会展示如下图对应的页面

在这里插入图片描述

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><style>#box {align-items: center;}#input-box {display: flex;align-items: center;}.label {white-space: nowrap;}.btn-box {padding-left: 50px;padding-top: 10px;}</style></head><body><div id="btn-box3"><button id="set-proxy-btn">设置代理</button></div><br><div id="btn-box4"><button id="open_manage_panel">打开管理面板</button></div><br><script src="/html/popup/popup.js"></script></body>
</html>

function set_proxy() {var config = {mode: "fixed_servers",rules: {proxyForHttp: {scheme: "http",host: "127.0.0.1",  // 代理IP, 调用后端接口获取到代理ip的时候将host 和 port配置为对应的地址和端口port: 80 //代理端口},proxyForHttps: {scheme: "http",host: "127.0.0.1",port: 443},bypassList: ["localhost", "127.0.0.1", "<local>"]}
};// 设置代理chrome.proxy.settings.set({ value: config, scope: 'regular' },function () {console.log("设置代理成功") });var originalIp = "";// 设置代理成功后校验代理是否正常,如果不需要校验也可以去掉下面的代码async function getCurrentIp() {let res = await fetch('http://api.ipify.org/');return await res.text();}// Get ip before setting proxygetCurrentIp().then(ip => {originalIp = ip;console.log(originalIp);});}function open_tabs() {chrome.tabs.create({url: './html/manage_panel/manage_panel.html'})
}
document.getElementById('open_manage_panel').onclick = open_tabs
document.getElementById('set-proxy-btn').onclick = set_proxy
// set_proxy()

可以设置代理,也可以点击管理面板在新的tab上打开一个页面, 如下图
在这里插入图片描述

content_script

content_script 我的理解是一个管理往网页注入js脚本的一个控制程序,负责管理注入到网页的 inject js脚本文件,可以跟被注入到网页的 inject js脚本进行通信,也可以跟程序页面或全局背景js进行通信,后面拦截到的数据主要通过它来获取转发到插件页面上,是一个数据中转、管理注入脚本的一个控制器

var comment_id_list  = []
var comment_data = {}// 转发popup指令  popup => content script => inject script
chrome.extension.onMessage.addListener(function (request, sender, sendResponse) {// 将inject拦截到的数据if (request.action === "get_show_data") {console.log("收到get_show_data请求")// comment_data 和 comment_id_list 是下面inject newtwork.js 中拦截到的数据存储变量,在content_script中可以直接使用 inject里面的变量sendResponse({comment_data: comment_data, comment_id_list: comment_id_list})}}
);// 监听数据
window.addEventListener("message", function(e) {if (e.data.action === 'comment_data'){// 监听message, 将 inject 里面的js 转发的数据存储到本地上comment_data = e.data.comment_datacomment_id_list = e.data.comment_id_list}}, false);// 插件启动的时候给background 全局对象发送一个请求,目的是让background缓存当前插件的tabid
chrome.runtime.sendMessage({type: "action"
});
inject

inject 是注入到页面的js文件,可以在这个js里面进行请求响应数据的拦截,上面博主分享的代码里面已经完成了数据的拦截,这里主要记录的是 注入页面的js如何和管理面板进行通信传递数据

正常来说 inject 里面拦截到的接口数据是不能直接和插件页面通信的,不过可以通过接口请求将数据传送到自己的服务器上, 如下图
在这里插入图片描述

在 inject 脚本拦截获取到数据之后,将数据内容直接发到直接的服务器上,需要注意后端服务器是否有跨域请求

第二种在页面展示数据的方法是 每次拦截到数据之后给content_script 存储起来,content_script 先是通过 chrome.runtime.sendMessage 给 background.js 发送一个数据,让background.js 获取到插件的tabid,然后每次接受到inject 注入的js转发的数据后存储起来,等到tab管理页面需要的时候转发给他

background.js
var tabid = ""// background.js
chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {tabid = sender.tab.id
});function get_tabid(){console.log("获取tabid: ", tabid)return tabid
}

background.js 是一个全局的对象,在浏览器开始的时候就存在了,它可以接收到 浏览器插件页面的调用,也可以接收到 content_script 给它发送的数据内容,本插件管理页面和content_script 之间的通信是通过 tabid来进行通信的,需要background.js 存储content_script 的tabid,以供 管理页面使用

管理页面
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>管理面板</title>
<link href="/css/style.css" rel="stylesheet" type="text/css" />
<script type="text/javascript" src="/js/config/jquery.min.js"></script><script type="text/javascript" src="/js/config/subnav.js"></script>
<script type="text/javascript" src="/html/manage_panel/manage_panel.js"></script>
</head>
<body>
<div  style="overflow: hidden; width: 80%; margin: auto"><br/>
<textarea rows="50" cols="250" id="text" style="padding: 40px; margin: auto; width: 100%;display: block"></textarea>
</div>
</body>
</html>
$(function() {// 获取background对象const background = chrome.extension.getBackgroundPage();// 获取这个background  全局对象中存储的插件作用的tabidvar tabid = background.get_tabid()// 获取插件的数据并渲染到html上    	chrome.tabs.query({active: true, currentWindow: true}, function(tabs){chrome.tabs.sendMessage(tabid, {"action": "get_show_data"}, function(response){console.log("rrrrrrrrrrr", response)var new_comment_data = response.comment_datavar new_comment_id_list = response.comment_id_listvar html = ""for (let i = 0; i < new_comment_id_list.length; i++) {html += `\n ${JSON.stringify(new_comment_data[new_comment_id_list[i]])} \n\n\n\n`}document.getElementById("text").value += html});});
})

最后的结果就类似这样
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/132736.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

npm install报错

在命令提示符窗口下载npm&#xff0c;报错如下&#xff1a; $npm install报错信息如下&#xff1a; npm WARN old lockfile npm WARN old lockfile The package-lock.json file was created with an old version of npm, npm WARN old lockfile so supplemental metadata must…

【数据结构】二叉树的链式结构及实现

目录 1. 前置说明 2. 二叉树的遍历 2.1 前序、中序以及后序遍历 2.2 层序遍历 3. 节点个数及高度等 4. 二叉树的创建和销毁 1. 前置说明 在学习二叉树的基本操作前&#xff0c;需先要创建一棵二叉树&#xff0c;然后才能学习其相关的基本操作。由于现在大家对二叉树结构…

软碟通制作启动盘

一、下载并安装软碟通 二、插入U盘&#xff0c;打开软碟通&#xff1b; 三、在软碟通中选择“文件”-“打开镜像文件”&#xff0c;选择要制作成启动盘的ISO镜像文件&#xff1b; 1.打开要制作的iso文件 选择对应的iso文件 四、在软碟通中选择“启动”-“写入硬盘”&#xff…

【开源电商网站】(2),使用docker-compose和dockerfile进行配置,设置自定义的镜像,安装插件,增加汉化包,支持中文界面汉化。

项目相关代代码地址 相关内容&#xff1a; https://blog.csdn.net/freewebsys/category_12461196.html 原文地址&#xff1a; https://blog.csdn.net/freewebsys/article/details/133666433 包括以下运行的详细代码&#xff1a; https://gitee.com/study-demo-all/oscommerc…

火狐浏览器页面翻译

打开扩展 扩展搜索tran 点击谷歌快译组件 设置翻译语言 安装完成后即可右键翻译页面

el-table组件的封装

前言&#xff1a;仔细看懂本篇博客&#xff0c;玩转element table 不成问题 &#xff0c;个人理解所谓封装&#xff0c;就是把经常都要公用的东西&#xff0c;拿出来&#xff0c;可以多次复用。公用方法&#xff0c;公用页面都可以封装。 其实封装也并不是有多难&#xff0c;思…

力扣 -- 516. 最长回文子序列

解题步骤&#xff1a; 参考代码&#xff1a; class Solution { public:int longestPalindromeSubseq(string s) {int ns.size();vector<vector<int>> dp(n,vector<int>(n));//记得从下往上填表for(int in-1;i>0;i--){//记得i是小于等于j的for(int ji;j&l…

SQL:left join、right join 究竟什么区别?

1、SQL join 分三种 1&#xff09;inner join&#xff08;内连接&#xff0c;也叫等值连接&#xff09; 显示两个表中有联系的所有数据&#xff0c;是默认方式。 2&#xff09;cross join&#xff08;交叉连接&#xff09; 两个表格做笛卡尔积&#xff0c;显示的数据行数是…

多服务器云探针源码(服务器云监控)/多服务器多节点_云监控程序python源码

源码简介&#xff1a; 多服务器云探针源码(服务器云监控),支持python多服务器多节点&#xff0c;云监控程序源码。它是一款很实用的云探针和服务器云监控程序源码。使用它可以帮助管理员能够快速监控和管理各种服务器和节点&#xff0c;实用性强。 源码链接&#xff1a; 网盘…

办公室人人在用的iTab桌面真的好用吗?

本人坐标北京&#xff0c;在一家中型互联网公司当社畜多年。最近发现一个奇怪的现象&#xff0c;我工位前后左右的同事都跟我在用一样的浏览器桌面——iTab新标签页。我表示莫非真的英雄所见略同&#xff1f; 我是去年1月份在刷B站时偶然刷到一条评论&#xff0c;有人分享自己…

Xception:使用Tensorflow从头开始实现

一、说明 近年来&#xff0c;卷积神经网络已成为计算机视觉领域的主要算法&#xff0c;开发设计它们的方法一直是相当的关注。Inception模型似乎能够用更少的参数学习更丰富的表示。它们是如何工作的&#xff0c;以及它们与常规卷积有何不同&#xff1f;本文将用tensorflow实现…

(部署服务器系列一)虚拟机模拟部署服务器

1、下载安装vmware 15 &#xff08;win7最高支持版&#xff09; 2、下载安装CentOS 配置2核2g&#xff08;最少&#xff09;磁盘100g&#xff08;不会实际占有&#xff09;选择时区-上海配置分区&#xff1a;https://blog.csdn.net/qq_35363507/article/details/127390889 &a…