浏览器插件开发爬虫记录
常用爬虫有各种各样的反爬限制,而如果是小数据量并且该网站反爬手段非常厉害的前提下,可以考虑使用浏览器插件作为爬虫手段
基本代码来源于这位博主分享的插件代码, 主要在他的基础上加了 请求代理、管理面板、脚本注入拦截到的请求数据和管理面板之间的交互
基本项目结构如下:
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});});
})
最后的结果就类似这样
相关文章:

浏览器插件开发爬虫记录
常用爬虫有各种各样的反爬限制,而如果是小数据量并且该网站反爬手段非常厉害的前提下,可以考虑使用浏览器插件作为爬虫手段 基本代码来源于这位博主分享的插件代码, 主要在他的基础上加了 请求代理、管理面板、脚本注入拦截到的请求数据和管…...

万万没想到,我用文心一言开发了一个儿童小玩具
最近关注到一年一度的百度世界大会今年将于10月17日在北京首钢园举办,本期大会的主题是“生成未来(PROMPT THE WORLD)”。会上,李彦宏会做主题为「手把手教你做AI原生应用」的演讲,比较期待 Robin 会怎么展示。据说&am…...

SQL sever中的视图
目录 一、视图概述: 二、视图好处 三、创建视图 法一: 法二: 四、查看视图信息 五、视图插入数据 六、视图修改数据 七、视图删除数据 八、删除视图 法一: 法二: 一、视图概述: 视图是一种常用…...
如何理解数据序列化
数据序列化是一个将数据结构或对象状态转换为一个可以存储或传输的格式的过程。序列化后的数据可以存放在文件中、数据库中或通过网络传输。反序列化是将序列化数据恢复为原始数据结构或对象的过程。 数据序列化格式可以理解为一种约定或规范,它定义了如何表示和编码数据以便…...

07_项目开发_用户信息列表
1 用户信息列表内容展示 用户信息列表,主要完成用户信息的添加、删除、修改和查找功能。 用户列表页面效果: 单击“添加用户”按钮,进入添加用户页面。 填写正确的信息后,单击“添加用户”按钮,会直接跳转到用户列表…...
flutter ios打包
在 Flutter 中打包 iOS 应用程序分为两步: 生成 iOS 项目文件 在 Flutter 项目根目录下执行以下命令: flutter create --ios-language swift .这个命令会在当前目录下生成 iOS 项目文件,并且默认使用 Swift 语言编写。 使用 Xcode 打包 …...

【无公网IP内网穿透】基于NATAPP搭建Web站点
🎉🎉欢迎来到我的CSDN主页!🎉🎉 🏅我是Java方文山,一个在CSDN分享笔记的博主。📚📚 🌟推荐给大家我的专栏《.内网穿透》。🎯🎯 &#…...

智能AI创作系统ChatGPT详细搭建教程/AI绘画系统/支持GPT联网提问/支持Prompt应用/支持国内AI模型
一、智能AI创作系统 SparkAi创作系统是基于OpenAI很火的ChatGPT进行开发的Ai智能问答系统,支持OpenAI GPT全模型国内AI全模型。本期针对源码系统整体测试下来非常完美,可以说SparkAi是目前国内一款的ChatGPT对接OpenAI软件系统。那么如何搭建部署AI创作…...

【技能树笔记】网络篇——练习题解析(五)
目录 前言 一、应用层的作用 1.1 应用层的作用 二、HTTP协议 2.1 HTTP协议 三、FTP协议 3.1 FTP协议 四、DNS协议 4.1 DNS协议 五、DHCP协议 5.1 DHCP协议 六、邮件协议 6.1 电子邮件协议 总结 前言 本篇文章给出了CSDN网络技能树中的部分练习题解析,…...
Java集合(二)--- 集合元素的遍历操作Iterator以及foreach
文章目录 一、使用迭代器Iterator接口1.说明2.代码 二、foreach循环,用于遍历集合、数组 提示:以下是本篇文章正文内容,下面案例可供参考 一、使用迭代器Iterator接口 1.说明 1.内部的方法: hasNext() 和 next() 2.集合对象每次调iterator…...

数据结构:排序- 插入排序(插入排序and希尔排序) , 选择排序(选择排序and堆排序) , 交换排序(冒泡排序and快速排序) , 归并排序
目录 前言 复杂度总结 预备代码 插入排序 1.直接插入排序: 时间复杂度O(N^2) \空间复杂度O(1) 复杂度(空间/时间): 2.希尔排序: 时间复杂度 O(N^1.3~ N^2) 空间复杂度为O(1) 复杂度(空间/时间&#…...

IOT 围炉札记
文章目录 一、蓝牙二、PAN1080三、IOT OS四、通讯 一、蓝牙 树莓派上的蓝牙协议 BlueZ 官网 BlueZ 官方 Linux Bluetooth 栈 oschina 二、PAN1080 pan1080 文档 三、IOT OS Zephyr 官网 Zephyr oschina Zephyr github Zephyr docs 第1章 Zephyr简介 第2章 Zephyr 编译环…...

小谈设计模式(24)—命令模式
小谈设计模式(24)—命令模式 专栏介绍专栏地址专栏介绍 命令模式角色分析命令(Command)具体命令(ConcreteCommand)接收者(Receiver)调用者(Invoker)客户端&am…...

9.HTML
文章目录 1.HTML 常见标签1.1注释标签1.2标题标签: h1-h61.3段落标签: p1.4换行标签: br1.5综合案例: 展示博客1.6格式化标签1.7图片标签: img1.8超链接标签: a1.9综合案例: 展示博客21.10表格标签1.10.1基本使用1.10.2合并单元格 1.11列表标签1.12表单标签1.13无语义标签: div…...

分层强化学习 综述论文阅读 Hierarchical Reinforcement Learning: A Comprehensive Survey
分层强化学习 综述论文阅读 Hierarchical Reinforcement Learning: A Comprehensive Survey 摘要一、介绍二、基础知识回顾2.1 强化学习2.2 分层强化学习2.2.1 子任务符号2.2.2 基于半马尔可夫决策过程的HRL符号 2.3 通用项定义 三、分层强化学习方法3.1 学习分层策略 (LHP)3.1…...

TensorFlow入门(十五、数据读取机制(2))
使用Dataset创建和读取数据集,作为TensorFlow模型创建输入管道的新方式,使用性能比使用feed_dict或队列式管道的性能高很多,使用也更加简洁容易。也是google强烈推荐的数据读取方式,对于TensorFlow而言,十分重要。 Dataset是什么? Dataset的定义 : 它是一个含有相同类型元素且…...

Linux系统中实现便捷运维管理和远程访问的1Panel部署方法
文章目录 前言1. Linux 安装1Panel2. 安装cpolar内网穿透3. 配置1Panel公网访问地址4. 公网远程访问1Panel管理界面5. 固定1Panel公网地址 前言 1Panel 是一个现代化、开源的 Linux 服务器运维管理面板。高效管理,通过 Web 端轻松管理 Linux 服务器,包括主机监控、…...
Rancher清理节点
本节介绍如何从一个 Rancher 创建的 Kubernetes 集群中断开一个节点,并从该节点中删除所有 Kubernetes 组件。此过程允许您将释放节点资源,将节点用于其他用途。 当您使用 Rancher 创建集群节点 时,将创建资源(容器/虚拟网络接口)和配置项(证…...

C++-Mongoose(1)-http-server
Mongoose is a network library for C/C. It implements event-driven non-blocking APIs for TCP, UDP, HTTP, WebSocket, MQTT. mongoose很小巧,只有两个文件mongoose.h/cpp,拿来就可以用. 下载地址: https://github.com/cesanta/mongoo…...
Linux中openvswitch配置网桥详解
以下是对给出的命令进行逐行解释和注释: # 安装openvswitch软件包,并自动确认所有提示信息使用默认值(-y参数) dnf install openvswitch -y# 启动openvswitch服务 systemctl start openvswitch# 设置openvswitch服务开机启动 sys…...

C++_核心编程_多态案例二-制作饮品
#include <iostream> #include <string> using namespace std;/*制作饮品的大致流程为:煮水 - 冲泡 - 倒入杯中 - 加入辅料 利用多态技术实现本案例,提供抽象制作饮品基类,提供子类制作咖啡和茶叶*//*基类*/ class AbstractDr…...
mongodb源码分析session执行handleRequest命令find过程
mongo/transport/service_state_machine.cpp已经分析startSession创建ASIOSession过程,并且验证connection是否超过限制ASIOSession和connection是循环接受客户端命令,把数据流转换成Message,状态转变流程是:State::Created 》 St…...
Go 语言接口详解
Go 语言接口详解 核心概念 接口定义 在 Go 语言中,接口是一种抽象类型,它定义了一组方法的集合: // 定义接口 type Shape interface {Area() float64Perimeter() float64 } 接口实现 Go 接口的实现是隐式的: // 矩形结构体…...

DBAPI如何优雅的获取单条数据
API如何优雅的获取单条数据 案例一 对于查询类API,查询的是单条数据,比如根据主键ID查询用户信息,sql如下: select id, name, age from user where id #{id}API默认返回的数据格式是多条的,如下: {&qu…...
【HarmonyOS 5 开发速记】如何获取用户信息(头像/昵称/手机号)
1.获取 authorizationCode: 2.利用 authorizationCode 获取 accessToken:文档中心 3.获取手机:文档中心 4.获取昵称头像:文档中心 首先创建 request 若要获取手机号,scope必填 phone,permissions 必填 …...
Go 语言并发编程基础:无缓冲与有缓冲通道
在上一章节中,我们了解了 Channel 的基本用法。本章将重点分析 Go 中通道的两种类型 —— 无缓冲通道与有缓冲通道,它们在并发编程中各具特点和应用场景。 一、通道的基本分类 类型定义形式特点无缓冲通道make(chan T)发送和接收都必须准备好࿰…...

使用Spring AI和MCP协议构建图片搜索服务
目录 使用Spring AI和MCP协议构建图片搜索服务 引言 技术栈概览 项目架构设计 架构图 服务端开发 1. 创建Spring Boot项目 2. 实现图片搜索工具 3. 配置传输模式 Stdio模式(本地调用) SSE模式(远程调用) 4. 注册工具提…...

深入浅出深度学习基础:从感知机到全连接神经网络的核心原理与应用
文章目录 前言一、感知机 (Perceptron)1.1 基础介绍1.1.1 感知机是什么?1.1.2 感知机的工作原理 1.2 感知机的简单应用:基本逻辑门1.2.1 逻辑与 (Logic AND)1.2.2 逻辑或 (Logic OR)1.2.3 逻辑与非 (Logic NAND) 1.3 感知机的实现1.3.1 简单实现 (基于阈…...
PostgreSQL——环境搭建
一、Linux # 安装 PostgreSQL 15 仓库 sudo dnf install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-$(rpm -E %{rhel})-x86_64/pgdg-redhat-repo-latest.noarch.rpm# 安装之前先确认是否已经存在PostgreSQL rpm -qa | grep postgres# 如果存在࿰…...
Python 高级应用10:在python 大型项目中 FastAPI 和 Django 的相互配合
无论是python,或者java 的大型项目中,都会涉及到 自身平台微服务之间的相互调用,以及和第三发平台的 接口对接,那在python 中是怎么实现的呢? 在 Python Web 开发中,FastAPI 和 Django 是两个重要但定位不…...