谷歌插件Image downloader开发之 content script

自己运营了一个公众号,在发文章的时候,需要在网上找一些图,而有些网站的图片可能隐藏在属性或者背景图中,要下载的时候经常审查元素,查看源码,不太方便,最近在看一些谷歌插件的api,便顺手做了一个插件Image downloader。源码放到了github上,顺便学习并用了一下git。地址:https://github.com/yeyuqiudeng/imageDownloader

功能

Image downloader有下面几个功能:

  • 收集所有的img标签src的图片链接
  • 收集所有的背景图片链接
  • 可以根据定义的规则,收集标签属性中的链接
  • 支持图片大小筛选
  • 显示图片的原始大小

预览

manifest.json

插件用到谷歌插件中的content script和popup。content script是注入到页面中的js,需要在manifest.json配置注入页面的规则,和注入那些js进入页面。在这个插件中,我的manifest.json是这样的:

{
  "manifest_version": 2,
  "name": "Image downloader",
  "description": "图片下载器,可以自定义属性下载规则",
  "version": "1.0",
  "browser_action": {
    "default_icon": "icon16.png",
    "default_popup": "/popup/popup.html"
  },
  "permissions": [
    "tabs",
    "downloads"
  ],
  "icons": {
        "16": "icon16.png",
        "48": "icon48.png",
        "128": "icon128.png"
    },
    "content_scripts": [{
        "matches": ["http://*/*", "https://*/*"],
        "js": ["common.js", "inject.js"]
    }]
}

content_scripts的配置表示要将common.js和inject.js注入到所有http和https的网站

common公共方法

在common里我定义了两个方法,一个用来显示错误信息,一个方法将图片的相对路径补全,在cdn地址前面加上http。

方法如下:

// 显示错误信息
const showMsg = (msg) => {
    let myDate = new Date();
    let now = myDate.toLocaleString();
    console.log(now + "【" + msg + "】");
};
// 拼接相对路径及cdn
const concatUrl = (url, domain) => {
    let fullPath = url
    if (/^\/[^\/]+/.test(url)) { // 是否为相对路径
        fullPath = domain + url
    }
    if (/^\/\//.test(url)) { // 是否为cdn
        fullPath = ‘http:‘ + url
    }
    return fullPath
}

不太熟悉正则,也不知道写得对不对。

其实这里不需要再要一个common.js的文件,只是上一次写插件的时候,公共的方法比较多,这次也将common.js留了下来。

content script

在注入页面的JS中,主要是三个方法,分别用来收集img标签的src地址,元素的背景图片和自定义属性规则的属性值

收集img标签的src值代码如下:

const getImgUrl = function() { // 获取所有图片的src值
    const allImg = document.querySelectorAll(‘img‘)
    const allImgUrl = []
    allImg.forEach((img) => {
        allImgUrl.push(concatUrl(img.src, domain))
    })
    return allImgUrl
}

其实就是获取img标签的集合,遍历集合并获取src的值,如果为相对路径或cdn路径,用concatUrl方法拼接成绝对路径,最后组成一个由url地址组成的数组。

获取背景图片的代码如下:

const getBackgroundImage = function() { // 获取背景图片
    const allDoms = document.querySelectorAll(‘*‘)
    const allBgImageUrl = []
    allDoms.forEach((element) => {
        let url = window.getComputedStyle(element)[‘background-image‘].match(/url\("(.+)"\)$/)
        if (url && url[1]) {
            allBgImageUrl.push(concatUrl(url[1], domain))
        }
    })
    return allBgImageUrl
}

通过getComputedStyle方法来获取所有元素的backgroundImage属性值,并将url地址提取出来,如果一个backgroundImage中有多个url,只取第一个,后面的就舍弃了。这个方法也是返回一个由地址组成的数组。

获取配置属性值的代码如下:

let configAttr = [‘data-src‘] // 配置的属性
const getConfigAttrUrl = function() { //  获取所有配置属性的值
    const attrUrl = []
    if (configAttr.length > 0) {
        configAttr.forEach((attr) => {
            attrUrl.push(...getAllAttr(attr))
        })
    }
    return attrUrl
}
const getAllAttr = function(attr) { // 获取对应属性的值
    const attrs = []
    const allDoms = document.querySelectorAll(‘[‘ + attr + ‘]‘)
    allDoms.forEach((dom) => {
        const attrValue = dom.getAttribute(attr)
        attrs.push(concatUrl(attrValue, domain))
    })
    return attrs
}

configAttr用来配置需要获取元素属性的规则,这里用了数组来接收多个配置规则,默认收集所有元素的data-src属性值。为什么会内置这个规则呢?因为很多网站都用了这个属性啊。

getAllAttr是根据传进来的属性获取属性值,getConfigAttrUrl是遍历属性规则,收集所有属性规则下的所有属性值,返回一个属性值数组。

图片不会在进入页面后马上就进行收集,只会在用户点击插件时才开始收集当前页面的图片,并将收集到的数据发送给popup处理。content script怎样与popup交互,下一篇文章再说。

最后,所有文章都会同步发送到微信公众号上,欢迎关注,欢迎提意见:

时间: 2024-10-29 02:00:35

谷歌插件Image downloader开发之 content script的相关文章

谷歌插件Image downloader开发之popup

Image downloader的交互逻辑是这样的:用户点击Image downloader的图标,会向页面(content script,见上一篇文章:谷歌插件Image downloader开发之 content script)发送收集图片事件,页面收集完图片后,将对应的图片地址数组发送给popup页处理.popup页就是点击谷歌插件图标所弹出来的页面.Image downloader的popup页是长成这样的: popup页包含的功能 popup页采用了vue1.0来做数据绑定,主要包含了

Android插件化开发之Hook StartActivity方法

第一步.先爆项目demo照片,代码不多,不要怕 第二步.应该知道Java反射相关知识 如果不知道或者忘记的小伙伴请猛搓这里,Android插件化开发基础之Java反射机制研究 http://blog.csdn.net/u011068702/article/details/49863931 第三步.应该知道Java静态代理知识 如果不知道或者忘记的小伙伴请猛搓这里,Android插件化开发基础之静态代理模式 http://blog.csdn.net/u011068702/article/detai

监控开发之用munin来自定义插件监控redis和mongodb

求监控组的大哥大妹子们干点事,真不容易 ! 要问他们是谁?  他们是神 .轻易别找他们,因为找了也是白找. 上次因为python和redis长时间brpop的时候,会有线程休眠挂起的情况,所有通知报警平台被下线了.这次算是完美解决了.再把他给上线.这两公司的告警已经开始往我这边的接口开始仍了. 这边正在改zabbix cmdb的控制,所以暂时不能登录.等搞好了后,让他们搞下redis和mogodb的监控,居然还让我发邮件和提供脚本及思路啥的...   一寻思,又要去zabbix,又要写脚本,还不

插件开发之360 DroidPlugin源码分析(四)Activity预注册占坑

请尊重分享成果,转载请注明出处: http://blog.csdn.net/hejjunlin/article/details/52258434 在了解系统的activity,service,broadcastReceiver的启动过程后,今天将分析下360 DroidPlugin是如何预注册占坑的?本篇文章主要分析Activity预注册占坑,Activity占了坑后又是什么时候开始瞒天过海欺骗AMS的?先看下Agenda: AndroidMainfest.xml中概览 Activity中关键方

Eclipse插件开发之TreeViewer

contentprovider在插件开发和RCP(Rich Client Platform)开发中常常被用到,譬如你要创建一个TreeViewer(树形控件)就需要一个ITreeContentProvider,如果要实现一个TableViewer(表控件)就需要一个IStructuredContentProvider,contentprovider主要的作用就是返回当前界面中的数据. 1.内容提供器(ITreeContentProvider) TreeViewer的内容提供器(ITreeCont

监控开发之用python扩展dstat插件自定义实时监控

dstat是一个python开源的实时监控工具,一般是用来做系统性能监控的.咱们这里只是提他的自定义插件开发,用来打造自己的dstat. 有朋友可能还没清楚是啥意思, 咱们查看系统的状体状态有人喜欢用vmstat,也有人喜欢用dstat.相比来说dstat的功能模块更全一点是,这里还只是说查看系统性能方面的 !   如果想一边查看,系统的各方面性能指标,还想看你应用的一些个负载相关,比如某个程序的负载,mongodb的锁lock百分比,mysql连接数...   懂了吧 ! 下面是dstat的插

插件开发之360 DroidPlugin源码分析(五)Service预注册占坑

请尊重分享成果,转载请注明出处: http://blog.csdn.net/hejjunlin/article/details/52264977 在了解系统的activity,service,broadcastReceiver的启动过程后,今天将分析下360 DroidPlugin是如何预注册占坑的?本篇文章主要分析Service预注册占坑,Service占了坑后又是什么时候开始瞒天过海欺骗AMS的?先看下Agenda: AndroidMainfest.xml中概览 Service中关键方法被h

Android插件化开发之OpenAtlas插件启动方式与插件启动广播

到现在为止已经写了6篇文章了 Android插件化开发之OpenAtlas初体验 Android插件化开发之OpenAtlas生成插件信息列表 Android插件化开发之OpenAtlas资源打包工具补丁aapt的编译 Android插件化开发之OpenAtlas插件适配 Android插件化开发之解决OpenAtlas组件在宿主的注册问题 Android插件化开发之OpenAtlas中四大组件与Application功能的验证 这篇文章主要介绍一下OpenAtlas插件的几种启动方式,在Atl

Android插件化开发之Atlas插件适配

前三篇文章,介绍了OpenAtlas的一些基本用法以及patch的aapt的编译方法. - Android插件化开发之Atlas初体验 - Android插件化开发之Atlas生成插件信息列表 - Android插件化开发之Atlas资源打包工具补丁aapt的编译 OpenAtlas的原则就是避免引入冗余的库.也就是宿主中提供了第三方库后,插件中就不要再引入该库,编译的时候以provided形式提供即可.最简单的例子就是v4,v7兼容库,应该避免引入.为了让我妈的插件脱离OpenAtlas也能独