11-13 17.29更新
项目结构如下:
├── backend # 后端处理
│ ├── __init__.py
│ ├── main # 功能函数
│ └── web # web函数
├── manage.py # 看名字就知道这是什么了
├── static # 前端静态文件
├── templates # 前端HTML模板
pywebview官方文档只能看api,不能看示例,示例不算是一个合格的项目。
一个PyWebview项目最关键的就是manage.py
文件,我写的项目的内容如下:
import logging
import webview
from io import StringIO
from contextlib import redirect_stdout
from backend.web import create_flask_app
logger = logging.getLogger(__name__)
if __name__ == '__main__':
stream = StringIO()
with redirect_stdout(stream):
window = webview.create_window(
"图片批处理工具 1.0.0",
create_flask_app(),
width=920,
resizable=False,
text_select=False,
background_color="#000"
)
webview.start(debug=True)
manage.py
是整个项目的调用文件,这个文件中的关键代码是:
window = webview.create_window(
"图片批处理工具 1.0.0",
create_flask_app(),
width=920,
resizable=False,
text_select=False,
background_color="#000"
)
webview.start(debug=True)
api文档:
创建一个新的 pywebview 窗口。首次调用此函数时将启动应用程序并占用程序主线程。您必须在单独的线程中执行您的程序逻辑。后续调用 create_window 将返回一个唯一窗口 uid,该窗口可用于引用 API 函数中的特定窗口。单窗口应用程序无需理会 uid,在函数调用中可以直接忽略它。
title
- 窗口标题
url
- 要加载的 URL。如果 URL 没有协议前缀,则将其解析为相对于应用程序入口点的路径。
js_api
- 将 js_api 类对象公开给当前 pywebview 窗口的 DOM 。JavaScript 可以通过 window.pywebview.api 对象来对 js_api 进行函数调用。回调函数可以接受一个参数的基本类型或对象。对象类型在 JavaScript 和 Python 间转换。函数在单独的非安全的线程中执行。
width
- 窗口宽度。默认值为 800px。
height
- 窗口高度。默认值为 600px。
resizable
- 窗口大小是否可以调整。默认为 True。
fullscreen
- 窗口全屏模式, 默认值为 False。
frameless
- 窗口无边框模式,默认值为 False。
min_size
- 窗口最小尺寸,元组类型 (width, height), 默认值为 (200x100)。
strings
- 窗口本地化语言配置,字符串的字典类型。默认值在 localization.py 中定义。
confirm_quit
- 窗口退出时是否显示确认对话框,默认值为False。
background_color
- 窗口的 WebView 在 loaded 之前的背景颜色。指定为十六进制颜色。默认为 white。
debug
- 启用调试模式,默认值为 False。
text_select
- 启用 WebView 的文档文本选择,默认值为 False。如需单独指定元素的文本选择,可以使用 CSS 的 user-select 属性。
manage.py
文件需要一个最基本的web项目作为连接前端和后端的过度/中间人,我用的是flask,我的flask项目结构为:
web
├── __init__.py
├── settings.py # flask配置文件
└── views
├── __init__.py
└── first.py # 如果视图函数复杂的话,可能需要分成若干个文件
每个人可能都有自己的flask项目结构,所以这方面就不再赘述了。
现在有了web了,接下来就是主角出场了——真正的后端功能函数,我给它起的名字是main,其结构为:
main
├── exceptions.py
├── filename_handler.py # 处理文件名
├── __init__.py
├── spider_handler.py # 处理爬虫
└── XXX_handler.py # 处理XXX
其实叫handlers或controllers可能更合适,只是叫main更能凸显它的重要性。
这里的函数就看自己怎么写了,这是整个项目的中心功能所在。
以spider_handler.py
为例,只是一个简单地爬取一个网页内所有图片的爬虫,其内容为:
class Spider:
def __init__(self, url: str, output: str, cookie: str = ''):
self.url: str = url
self.output: str = output
self.headers: dict = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.111 Safari/537.36'
}
if cookie:
self.header['Cookie'] = cookie
def __parse_image_urls(self, html: str) -> List[str]:
soup = BeautifulSoup(html, 'lxml')
img_tags = soup.find_all('img')
return [urljoin(self.url, img_tag['src']) for img_tag in img_tags]
def __save_all_image_file(self) -> int:
html = self.__get_html_response()
if html:
srcs = self.__parse_image_urls(html)
count = 0
for src in srcs:
img_response = requests.get(src, headers=self.headers)
if img_response.status_code == 200:
img_file = img_response.content
with open(f"{self.output}/spider_img_{ts}{suffix}", 'wb') as f:
f.write(img_file)
count += 1
except UnidentifiedImageError:
continue
return count
def __get_html_response(self) -> str:
response = requests.get(self.url, headers=self.headers)
if response.status_code == 200:
return response.text
else:
return ''
def get_all_images(self) -> dict:
try:
count = self.__save_all_image_file()
return {"status": 'ok', 'count': count}
except Exception as e:
return {'status': 'error', 'error': str(e)}
作为一个handler函数,一定要有返回值,方便在flask视图函数里调用并直接返回结果。
视图函数里的相关内容为:
from flask import Blueprint, jsonify, request
from backend.main.spider_handler import Spider
first = Blueprint("first_bp", __name__)
@first.route("/spider", methods=['POST'])
def spider_images_from_url():
data = request.json
url = data['url']
output = data['output']
spider = Spider(url, output)
response = spider.get_all_images()
return jsonify(response)
如第一张图的内容所见,当传递完url和output后,spider就开始运行了,这里有兴趣的人可以在前端展示进度,需要配合js完成。
11-18 10:09更新
正在写一个小项目,PC微信文件清理工具,进度有些慢,因为正在熟悉FastAPI,这个项目也是用来练习FastAPI的练手之作。
https://github.com/thep0y/WFCleanUpTool
11-18 18:05更新
Linux上的完成度示意图:
11-22 18:18更新
大概能返回文件夹的大小了
11-22 21:43更新
已完成初步的文件删除功能,会尽快打包发布。