Electron开发一个小应用

保命声明:笔者在校属于中水平学生,代码能力有限,若行文中有错漏之处欢迎大家指出。
项目地址:https://gitee.com/qsbye/electron-app

Electron

作为一个跨平台的桌面应用开发框架,Electron 的迷人之处在于,它是建立在 Chromium 和 Node.js 之上的 —— 二位分工明确,一个负责界面,一个负责背后的逻辑. Electron 能开发跨平台的桌面应用.

安装Electron Fidder集成开发环境

[https://www.electronjs.org/zh/docs/latest/]
[https://www.electronjs.org/fiddle#downloads]

获取数据

获取天气数据

[https://blog.csdn.net/weixin_36018773/article/details/114052637]
[https://www.cnblogs.com/bianchengxia/p/9234037.html]
[https://blog.csdn.net/weixin_42339078/article/details/100150188]
[http://www.tianqihoubao.com/weather/top/guangzhou.html]
[https://www.cnblogs.com/ngz311616/p/9525045.html]

因为使用天气API有限制,所以直接从百度网页获取,例如百度搜索“天气”就会自动根据ip地址给出所在城市的天气预报,获取天气信息几乎是没有限制。

百度天气
[https://weathernew.pae.baidu.com/weathernew/pc?query=广东广州天气&srcid=4982]

选择器路径:

[id="\31 "] > div.op_weather4_twoicon_container_div > div.op_weather4_twoicon > a.op_weather4_twoicon_today.OP_LOG_LINK > div.op_weather4_twoicon_shishi > div.op_weather4_twoicon_shishi_info

实时温度

<!--数值-->
[id="\31 "] > div.op_weather4_twoicon_container_div > div.op_weather4_twoicon > a.op_weather4_twoicon_today.OP_LOG_LINK > div.op_weather4_twoicon_shishi > div.op_weather4_twoicon_shishi_info > span.op_weather4_twoicon_shishi_title
<!--单位-->
[id="\31 "] > div.op_weather4_twoicon_container_div > div.op_weather4_twoicon > a.op_weather4_twoicon_today.OP_LOG_LINK > div.op_weather4_twoicon_shishi > div.op_weather4_twoicon_shishi_info > span.op_weather4_twoicon_shishi_data > i.op_weather4_twoicon_shishi_sup

当日温度范围

[id="\31 "] > div.op_weather4_twoicon_container_div > div.op_weather4_twoicon > a.op_weather4_twoicon_today.OP_LOG_LINK > p.op_weather4_twoicon_temp

风向、风速

[id="\31 "] > div.op_weather4_twoicon_container_div > div.op_weather4_twoicon > a.op_weather4_twoicon_today.OP_LOG_LINK > p.op_weather4_twoicon_wind

空气质量

<!--数值-->
[id="\31 "] > div.op_weather4_twoicon_container_div > div.op_weather4_twoicon > a.op_weather4_twoicon_today.OP_LOG_LINK > div.op_weather4_twoicon_realtime_quality_wrap > span > span:nth-child(1)
<!--等级-->
[id="\31 "] > div.op_weather4_twoicon_container_div > div.op_weather4_twoicon > a.op_weather4_twoicon_today.OP_LOG_LINK > div.op_weather4_twoicon_realtime_quality_wrap > span > span.op_weather4_twoicon_aqi_text_today

天气

<!--实时天气-->
[id="\31 "] > div.op_weather4_twoicon_container_div > div.op_weather4_twoicon > a.op_weather4_twoicon_today.OP_LOG_LINK > div.op_weather4_twoicon_shishi > div.op_weather4_twoicon_shishi_info > span.op_weather4_twoicon_shishi_data > i.op_weather4_twoicon_shishi_sub
<!--当日天气-->
[id="\31 "] > div.op_weather4_twoicon_container_div > div.op_weather4_twoicon > a.op_weather4_twoicon_today.OP_LOG_LINK > p.op_weather4_twoicon_weath

当日公历、农历

[id="\31 "] > div.op_weather4_twoicon_container_div > div.op_weather4_twoicon > a.op_weather4_twoicon_today.OP_LOG_LINK > p.op_weather4_twoicon_date

使用墨迹天气

npm install request --save // http请求库
npm install cheerio --save // 分析html工具
npm install express --save // nodejs web框架

脚本:

const request = require("request")
const cheerio = require("cheerio")
const weatherURL = 'https://tianqi.moji.com/weather/china/Guangdong/guangzhou'

// 获取墨迹天气提示信息
function getWeatherTips(url) {
    return new Promise((resolve,reject)=>{
    	request(weatherURL,(error,res,body)=>{
    	  if (!error) {
    	    let html = res.body || "";
    		let $ =cheerio.load(html)
    		let temp = $('.wea_weather em').text().trim()+'℃'
    		let desc = $('.wea_weather b').text().trim()
    		let water = $('.wea_about span').text().trim()
    		let win = $('.wea_about em').text().trim()
    		let tips = $('.wea_tips em').text().trim()
    		let words=`今日${city}天气\n${desc}\n温度:${temp}\n湿度:${water}\n风力:${win}\n${tips}`
    		resolve(words)
    	} else {
    		reject(error)
    	}      
      })
   })   
}

获取网速

[https://segmentfault.com/a/1190000040771061?sort=newest]

一言

这里不用API方式,而是用网页获取方式
网址[https://hitokoto.cn]

<!--文本-->
#hitokoto_text
<!--出处-->
#hitokoto_author

毒鸡汤

https://www.lioncp.cn/du.php

#text

每日一图

[https://zhuanlan.zhihu.com/p/136867451]
[https://wallhaven.cc/help/api]

<div style="background-image: url(http://tool.liumingye.cn/bingimg/img.php);"></div>
<img src="http://tool.liumingye.cn/bingimg/img.php" />
http://tool.liumingye.cn/bingimg/img.php

生成网页截图

[http://wenku.kuryun.com/docs/phantomjs/screencapture.html]

npm install --global phantomjs #无头浏览器
npm install --global pageres-cli

开始

[https://www.electronjs.org/zh/docs/latest/tutorial/tutorial-first-app]

初始化npm项目

mkdir my-electron-app && cd my-electron-app
npm init


初始化后会生成package.json,存储项目配置
程序的入口点为main.js

在 package.json 中指定的脚本文件 main 是所有 Electron 应用的入口点。 这个文件控制 主程序 (main process),它运行>在 Node.js 环境里,负责控制您应用的生命周期、显示原生界面、执行特殊操作并管理渲染器进程 (renderer processes)

打包后的应用本身会包含 Electron 的二进制文件,但是开发环境需要安装electron

npm install electron --save-dev

安装需要喝一杯奶茶的时间(本土化一点,歪果仁喝一杯咖啡的时间😏)


npm换源:[https://www.cnblogs.com/wyq1995/p/13651904.html]
第一种:npm config set registry http://registry.npm.taobao.org/
第二种:安装cnpm,npm install -g cnpm --registry=https://registry.npm.taobao.org
然后以后都是用cnpm安装插件,cnpm install xxx
第三种:使用nrm

1.下载nrm:npm install -g nrm

2.列出可以选择的源:nrm ls

3.选择想要使用的源:nrm use taobao

4.查看当前npm使用的源:npm config get registry

5.后续的想安装什么插件直接使用npm install xxx就行了


然后会有node_modules文件夹存放可执行文件和package-lock.json存储依赖需求.
Electron 遵循 JavaScript 传统约定,以帕斯卡命名法 (PascalCase) 命名可实例化的类 (如 BrowserWindow, Tray 和 Notification),以驼峰命名法 (camelCase) 命名不可实例化的函数、变量等 (如 app, ipcRenderer, webContents) 。
Electron 的很多核心模组是 Node.js 事件触发器,遵守 Node.js 的异步事件驱动架构。 app 模块就是其中一个。
您应用中的每个页面都在一个单独的进程中运行,我们称这些进程为 渲染器 (renderer) 。 渲染器也能访问前端开发常会用到的 API 和工具,例如用于打包并压缩代码的 webpack,还有用于构建用户界面的 React 。

报错处理

  • 引入外部文件,报错

Refused to load the image 'https://ss0.bdstatic.com/70cFuHSh_Q1YnxGkpoWK1HF6hhy/it/u=1971525978,455276806&fm=26&gp=0.jpg?rd=_1664896428274' because it violates the following Content Security Policy directive: "default-src 'self'". Note that 'img-src' was not explicitly set, so 'default-src' is used as a fallback.
解决方案
[https://www.cnblogs.com/xkxf/p/15553510.html]

<meta http-equiv="Content-Security-Policy" content="default-src 'self' https://ss0.bdstatic.com https://www.baidu.com; script-src 'self'; style-src 'self' 'unsafe-inline';img-src 'self' https://ss0.bdstatic.com https://www.baidu.com";>

[https://www.jianshu.com/p/74ea9f0860d2]
原因就是有一个CSP安全限制,我们需要允许从https://ss0.bdstatic.com https://www.baidu.com网址加载
效果:

www.baidu.com/search/error.html:1          GET https://www.baidu.com/search/error.html net::ERR_TIMED_OUT

可以访问设置的网址,但是百度的图片没有这么容易访问😭
另外找了一张图片:https://mirrors.tuna.tsinghua.edu.cn/static/img/logo-small@2x.png?rd=_
注意在图片后添加 rd=_" +new Date().getTime(),否则浏览器会缓存当前图片就不去加载了,影响到测速

  • '\$ '符号报错,网页引用jQuery在Electron运行出现"\$ is not defined"

[https://www.cnblogs.com/junchu25/p/11593604.html]
引用jQuery1.8.2版本

 <script src="./jquery-1.8.2.min.js"></script>

代码

点击查看代码

index.html

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <!-- https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP -->
    <meta http-equiv="Content-Security-Policy" content="default-src 'self' https://ss0.bdstatic.com https://www.baidu.com https://music.163.com https://widget.heweather.net; script-src 'self'; style-src 'self' 'unsafe-inline';img-src 'self' https://ss0.bdstatic.com https://www.baidu.com https://mirrors.tuna.tsinghua.edu.cn http://www.qsbye.cn http://tool.liumingye.cn https://www.bing.com https://cn.bing.com;";>
    <link href="./styles.css" rel="stylesheet">
    <title>桌面信息屏</title>
  </head>
  <body class="glass">
    <h1>桌面信息屏</h1>
    <!--网速显示-->
    <div class="signal"></div>
    <!--结束网速显示-->
    <!--开始天气显示-->
    <h4 id="tianqi"></h4>
  </br>
    <h4 id="fengli"></h4>
    <!-- 天气 -->
    <div class="weather card">
    <p>今日天气:晴</p>
    <div id="he-plugin-simple" style="display: contents;"></div>
    <script>
    WIDGET = {
        CONFIG: {
            "modules": "12034",
            "background": 5,
            "tmpColor": "888",
            "tmpSize": 14,
            "cityColor": "888",
            "citySize": 14,
            "aqiSize": 14,
            "weatherIconSize": 24,
            "alertIconSize": 18,
            "padding": "10px 10px 10px 10px",
            "shadow": "1",
            "language": "auto",
            "borderRadius": 5,
            "fixed": "false",
            "vertical": "middle",
            "horizontal": "left",
            "key": "a922adf8928b4ac1ae7a31ae7375e191"
        }
    }
    </script>
    <script src="https://widget.heweather.net/simple/static/js/he-simple-common.js?v=1.1"></script>
</div>
<!-- 天气 end -->
    <!--结束天气显示-->
    <!--每日一图卡片-->
    <div class="card" src="http://www.qsbye.cn/more/bing_daily_img.php">
      <p>天天天晴😊</p>
      <img src="http://www.qsbye.cn/more/bing_daily_img.php" width="200" height="100" style="border-radius: 10px;"/>
  </div>
    <div class="card">
  <img src="http://tool.liumingye.cn/bingimg/img.php" width="200" height="100"  style="border-radius: 10px;" />
  <img id="signal_ico" src="./bq1.png" width="26" height="18" title="强"><h5 id="speed"></h5>
    </div>
    <!--结束每日一图-->
    <!--网易云音乐-->
      <div class="music card"><iframe src="https://music.163.com/outchain/player?type=2&amp;id=864711417&amp;auto=1&amp;height=66" width="330" height="86" frameborder="no" marginwidth="0" marginheight="0"></iframe></div>
    <!--结束网易云音乐-->
    <!-- You can also require other files to run in this process -->
    <script src="./jquery-1.8.2.min.js"></script>
    <script src="./renderer.js"></script>
  </body>
</html>

styles.css

/* styles.css */
p{
  font-family: Arial, Helvetica, sans-serif;
}
body{
    background-image:url(bg3.jpg);
    background-color: skyblue;
    background-size: cover;
    background-attachment:fixed;
    width: 800px;
    height: 600px;
    -webkit-backdrop-filter: blur(10px);
    backdrop-filter: blur(10px);
}
/*毛玻璃效果*/
.glass{
    -webkit-backdrop-filter: blur(10px);
    backdrop-filter: blur(10px);
}
/*卡片效果*/
.card {
    width: 400px;
    height: auto;
    padding: 2rem;
    border-radius: 1rem;
    background: rgba(255, 255, 255, .7);
    -webkit-backdrop-filter: blur(10px);
    backdrop-filter: blur(10px);
    margin: 5rem;
  }
  
  .card-title {
    margin-top: 0;
    margin-bottom: .5rem;
    font-size: 1.2rem;
  }
  
  p, a {
    font-size: 1rem;
  }
  
  a {
    color: #4d4ae8;
    text-decoration: none;
  }
  .glass h1{
    color:aliceblue;
    font-family: Arial, Helvetica, sans-serif;
  }
/* Add styles here to customize the appearance of your app */

其他文件保持默认即可.

测试页面

#注意命令是node不是npm😂
node main.js

或者

npm start

打包为可执行文件

npm install electron-packager -g
electron-packager . HelloWorld --win --out ./HelloWorldApp --arch=x64  --electron-version=19.0.6 --icon=./icon.icns --app-version=0.0.1 --overwrite --ignore=node_modules
# --platform=win32可用于指定平台
#会下载需要的依赖:
#注意electron-version需要和package.json中的匹配才能开始打包,不然报错read ETIMEDOUT.
Downloading electron-v19.0.6-darwin-x64.zip: [============================================================] 100% ETA: 0.0 seconds
Packaging app for platform darwin x64 using electron v19.0.6

效果



内心os:

posted @ 2022-11-28 13:09  qsBye  阅读(447)  评论(0编辑  收藏  举报