提交 03fcb3f7 编写于 作者: Q qq_38870145

Tue Apr 1 20:53:00 CST 2025 inscode

上级 aa1e04bd
print('欢迎来到 InsCode') import uvicorn as uvicorn
\ No newline at end of file from fastapi import (
FastAPI,
Response,
)
from fastapi.middleware.cors import CORSMiddleware
from PIL import Image
import io
from fastapi.responses import FileResponse
app = FastAPI()
# 添加 CORS 中间件
app.add_middleware(
CORSMiddleware,
allow_origins=["*"], # 允许所有来源
allow_credentials=True, # 允许凭证
allow_methods=["*"], # 允许所有 HTTP 方法
allow_headers=["*"], # 允许所有头部
)
import time,math
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import os
from PIL import Image
from time import sleep
cur_outlook_emai_img_path=''
# cut
cut_img_paths=[]
# full
full_img_paths=[]
def gen_dir():
cur_timestemp = int(round(time.time() * 1000))
dir = './screen_shot/outlook/{ts}'.format(ts=cur_timestemp)
os.makedirs(dir, exist_ok=True)
return dir
def cut_img(screenshot_path,element,baseDir,loc):
# 获取元素坐标和尺寸
location = element.location # {x: number, y: number}
size = element.size # {width: number, height: number}
# 计算裁剪区域 (左, 上, 右, 下)
left = location['x']
top = location['y']
right = location['x'] + size['width']
bottom = location['y'] + size['height']
# 使用 Pillow 裁剪图像
image = Image.open(screenshot_path)
cropped_image = image.crop((left, top, right, bottom))
cut_file_name=f"{baseDir}/cut_{loc}.png"
cropped_image.save(cut_file_name)
global cut_img_paths
cut_img_paths.append(cut_file_name)
def join_images(png1, png2, size=0, output=f'{dir}/temp_result.png'):
"""
图片拼接
:param png1: 图片1
:param png2: 图片2
:param size: 两个图片重叠的距离
:param output: 输出的图片文件
:return:
"""
size = size * 2
img1, img2 = Image.open(png1), Image.open(png2)
size1, size2 = img1.size, img2.size
joint = Image.new('RGB', (size1[0], size1[1] + size2[1] - size))
loc1, loc2 = (0, 0), (0, size1[1] - size)
joint.paste(img1, loc1)
joint.paste(img2, loc2)
joint.save(output)
sleep(.5)
def vertical_concatenate_with_crop(image_paths, output_path, crop_height=100):
"""
纵向拼接多图,并对第二张图裁剪指定高度
:param image_paths: 图片路径列表(按顺序从上到下)
:param output_path: 输出文件路径
:param crop_height: 第二张图裁剪的高度(默认 100px)
"""
images = []
# 读取并处理图片
for idx, path in enumerate(image_paths):
img = Image.open(path)
if idx >= 1: # 第二张图之后裁剪
width, height = img.size
# 确保裁剪高度不超出原图范围
actual_crop = min(crop_height, height)
print('actual_crop',actual_crop)
# 左上
img = img.crop((0, actual_crop, width, height))
images.append(img)
# 计算总高度和最大宽度
total_height = sum(img.height for img in images)
max_width = max(img.width for img in images)
# 创建空白画布并拼接
merged = Image.new('RGB', (max_width, total_height))
y_offset = 0
for img in images:
# 居中处理宽度不一致的图片
x_offset = (max_width - img.width) // 2
merged.paste(img, (x_offset, y_offset))
y_offset += img.height
merged.save(output_path)
global cur_outlook_emai_img_path
cur_outlook_emai_img_path=output_path
def screen_shot(driver):
global cut_img_paths
# cut
cut_img_paths = []
global full_img_paths
# full
full_img_paths = []
dir=gen_dir()
# 当前滚动高度
scrollTop=driver.execute_script(
'return document.getElementById("ConversationReadingPaneContainer").childNodes[1].childNodes[0].scrollTop;')
# 可滚动高度范围
scrollHeight=driver.execute_script(
'return document.getElementById("ConversationReadingPaneContainer").childNodes[1].childNodes[0].scrollHeight;')
# 渲染的可视区域
clientHeight=driver.execute_script(
'return document.getElementById("ConversationReadingPaneContainer").childNodes[1].childNodes[0].clientHeight;')
print('scrollTop', scrollTop,type(scrollTop))
print('scrollHeight',scrollHeight)
print('clientHeight', clientHeight)
lastScrollTop=scrollTop
# 次数索引
i=0
# 等待元素加载并可见
element = WebDriverWait(driver, 10).until(
EC.visibility_of_element_located((By.ID, "ConversationReadingPaneContainer"))
)
window_height = driver.execute_script('return window.innerHeight;')
if lastScrollTop<scrollHeight:
img_path=f'{dir}/custom_{i}.png'
driver.save_screenshot(img_path)
cut_img(img_path,element,dir,i)
full_img_paths.append(img_path)
# 滚动底部 + 渲染高度 翻页滚动
while math.ceil(lastScrollTop+1) < scrollHeight:
end_rect_top = driver.execute_script('return document.querySelector(".g4Y3U").getBoundingClientRect().top;')
sleep(.5)
# end 结束 节点出现在可视区域 dom rect top<window height
if end_rect_top < window_height:
break
i += 1
# 加渲染高度 翻页 好拼接
lastScrollTop += clientHeight
driver.execute_script(
'document.getElementById("ConversationReadingPaneContainer").childNodes[1].childNodes[0].scrollTop={scrollTop}'.format(
scrollTop=lastScrollTop))
sleep(.5)
img_path = f'{dir}/custom_{i}.png'
driver.save_screenshot(img_path)
cut_img(img_path, element, dir, i)
full_img_paths.append(img_path)
else:
# 完整email
img_path=f'{dir}/full_screen_email.png'
driver.save_screenshot(img_path)
# 裁剪顶部高度 渲染高度
crop_height=driver.execute_script('return document.getElementById("ConversationReadingPaneContainer").firstChild.offsetHeight;')
# 8px padding
vertical_concatenate_with_crop(cut_img_paths, f'{dir}/result_email.png',crop_height+16)
def mapMSg(from_email='',from_title=''):
time.sleep(5)
driver_msg_dom=driver.find_element(By.CLASS_NAME,"customScrollBar")
print('driver_msg_dom',driver_msg_dom)
print('driver_doms',driver_msg_dom)
driver_tbody_dom=driver_msg_dom.find_elements(By.CLASS_NAME,'EeHm8')
print('driver_tbody_dom', driver_tbody_dom)
for trItem in driver_tbody_dom :
title=trItem.text
print('title',title)
print('title arr',title.split('\n'))
mailArr=title.split('\n')
if len(mailArr)>2 and from_email in mailArr[1] and from_title in mailArr[2]:
# 找到则点击
trItem.click()
sleep(5)
# 获取控制台日志
logs = driver.execute_script("return window.logs;")
print("操作日志:", logs)
screen_shot(driver)
break
time.sleep(1)
def run(from_email='',from_title=''):
global driver
options = webdriver.ChromeOptions()
options.add_experimental_option("detach", True)
# 步骤1获取到的User Data路径
options.add_argument(r'--user-data-dir=C:\Users\v_bymyma\AppData\Local\Google\Chrome\User Data\Default')
# 步骤2获取到的--profile-directory值
options.add_argument("--profile-directory=auto_py")
options.add_argument("--disable-web-security")
# driver_path = "C:\\Users\\v_bymyma\PycharmProjects\pythonProject\email\driver\chromedriver.exe"
driver = webdriver.Chrome(options=options)
driver.get('https://outlook.live.com/mail/0/')
mapMSg(from_email,from_title)
time.sleep(3)
driver.quit()
# outlook 截图 api /api/outlook_email_img?from_email=1432448610@qq.com&title=字体减半
@app.get("/api/outlook_email_img")
async def run_click_email(from_email: str, title: str):
try:
if from_email is None or title is None:
return {"code": -1, "msg": '参数from_email title 必填'}
run(from_email, title)
return FileResponse(
cur_outlook_emai_img_path,
media_type="image/png",
headers={"Cache-Control": "public, max-age=604800"} # 7天缓存
)
except Exception as e:
return {"code": -1, "msg": str(e)}
# 启动应用
if __name__ == "__main__":
uvicorn.run(app, host="127.0.0.1", port=9898)
...@@ -39,6 +39,61 @@ def cut_img(screenshot_path,element,baseDir,loc): ...@@ -39,6 +39,61 @@ def cut_img(screenshot_path,element,baseDir,loc):
cut_img_paths.append(cut_file_name) cut_img_paths.append(cut_file_name)
def join_images(png1, png2, size=0, output=f'{dir}/temp_result.png'):
"""
图片拼接
:param png1: 图片1
:param png2: 图片2
:param size: 两个图片重叠的距离
:param output: 输出的图片文件
:return:
"""
size = size * 2
img1, img2 = Image.open(png1), Image.open(png2)
size1, size2 = img1.size, img2.size
joint = Image.new('RGB', (size1[0], size1[1] + size2[1] - size))
loc1, loc2 = (0, 0), (0, size1[1] - size)
joint.paste(img1, loc1)
joint.paste(img2, loc2)
joint.save(output)
sleep(.5)
def vertical_concatenate_with_crop(image_paths, output_path, crop_height=100):
"""
纵向拼接多图,并对第二张图裁剪指定高度
:param image_paths: 图片路径列表(按顺序从上到下)
:param output_path: 输出文件路径
:param crop_height: 第二张图裁剪的高度(默认 100px)
"""
images = []
# 读取并处理图片
for idx, path in enumerate(image_paths):
img = Image.open(path)
if idx >= 1: # 第二张图之后裁剪
width, height = img.size
# 确保裁剪高度不超出原图范围
actual_crop = min(crop_height, height)
print('actual_crop',actual_crop)
# 左上
img = img.crop((0, actual_crop, width, height))
images.append(img)
# 计算总高度和最大宽度
total_height = sum(img.height for img in images)
max_width = max(img.width for img in images)
# 创建空白画布并拼接
merged = Image.new('RGB', (max_width, total_height))
y_offset = 0
for img in images:
# 居中处理宽度不一致的图片
x_offset = (max_width - img.width) // 2
merged.paste(img, (x_offset, y_offset))
y_offset += img.height
merged.save(output_path)
def screen_shot(driver): def screen_shot(driver):
dir=gen_dir() dir=gen_dir()
# 当前滚动高度 # 当前滚动高度
...@@ -101,79 +156,7 @@ def screen_shot(driver): ...@@ -101,79 +156,7 @@ def screen_shot(driver):
# 8px padding # 8px padding
vertical_concatenate_with_crop(cut_img_paths, f'{dir}/result_email.png',crop_height+16) vertical_concatenate_with_crop(cut_img_paths, f'{dir}/result_email.png',crop_height+16)
def mapMSg(from_email='',from_title=''):
def vertical_concatenate_with_crop(image_paths, output_path, crop_height=100):
"""
纵向拼接多图,并对第二张图裁剪指定高度
:param image_paths: 图片路径列表(按顺序从上到下)
:param output_path: 输出文件路径
:param crop_height: 第二张图裁剪的高度(默认 100px)
"""
images = []
# 读取并处理图片
for idx, path in enumerate(image_paths):
img = Image.open(path)
if idx >= 1: # 第二张图之后裁剪
width, height = img.size
# 确保裁剪高度不超出原图范围
actual_crop = min(crop_height, height)
print('actual_crop',actual_crop)
# 左上
img = img.crop((0, actual_crop, width, height))
images.append(img)
# 计算总高度和最大宽度
total_height = sum(img.height for img in images)
max_width = max(img.width for img in images)
# 创建空白画布并拼接
merged = Image.new('RGB', (max_width, total_height))
y_offset = 0
for img in images:
# 居中处理宽度不一致的图片
x_offset = (max_width - img.width) // 2
merged.paste(img, (x_offset, y_offset))
y_offset += img.height
merged.save(output_path)
def join_images(png1, png2, size=0, output=f'{dir}/temp_result.png'):
"""
图片拼接
:param png1: 图片1
:param png2: 图片2
:param size: 两个图片重叠的距离
:param output: 输出的图片文件
:return:
"""
size = size * 2
img1, img2 = Image.open(png1), Image.open(png2)
size1, size2 = img1.size, img2.size
joint = Image.new('RGB', (size1[0], size1[1] + size2[1] - size))
loc1, loc2 = (0, 0), (0, size1[1] - size)
joint.paste(img1, loc1)
joint.paste(img2, loc2)
joint.save(output)
sleep(.5)
def run():
global driver
options = webdriver.ChromeOptions()
options.add_experimental_option("detach", True)
# 步骤1获取到的User Data路径
options.add_argument(r'--user-data-dir=C:\Users\v_bymyma\AppData\Local\Google\Chrome\User Data\Default')
# 步骤2获取到的--profile-directory值
options.add_argument("--profile-directory=auto_py")
options.add_argument("--disable-web-security")
# driver_path = "C:\\Users\\v_bymyma\PycharmProjects\pythonProject\email\driver\chromedriver.exe"
driver = webdriver.Chrome(options=options)
driver.get('https://outlook.live.com/mail/0/')
mapMSg()
def mapMSg():
time.sleep(5) time.sleep(5)
driver_msg_dom=driver.find_element(By.CLASS_NAME,"customScrollBar") driver_msg_dom=driver.find_element(By.CLASS_NAME,"customScrollBar")
print('driver_msg_dom',driver_msg_dom) print('driver_msg_dom',driver_msg_dom)
...@@ -181,51 +164,39 @@ def mapMSg(): ...@@ -181,51 +164,39 @@ def mapMSg():
driver_tbody_dom=driver_msg_dom.find_elements(By.CLASS_NAME,'EeHm8') driver_tbody_dom=driver_msg_dom.find_elements(By.CLASS_NAME,'EeHm8')
print('driver_tbody_dom', driver_tbody_dom) print('driver_tbody_dom', driver_tbody_dom)
for trItem in driver_tbody_dom: for trItem in driver_tbody_dom :
print('trItem',trItem)
title=trItem.text title=trItem.text
print('title',title) print('title',title)
if 'VideoCover' in str(title): print('title arr',title.split('\n'))
# 找到则点击 VideoCover mailArr=title.split('\n')
if len(mailArr)>2 and from_email in mailArr[1] and from_title in mailArr[2]:
# 找到则点击
trItem.click() trItem.click()
sleep(5)
time.sleep(2)
time.sleep(5)
# 获取控制台日志 # 获取控制台日志
logs = driver.execute_script("return window.logs;") logs = driver.execute_script("return window.logs;")
print("操作日志:", logs) print("操作日志:", logs)
# html2canvas = """
# if(!html2canvas){
# var s=document.createElement('script');
# s.src='https://html2canvas.hertzen.com/dist/html2canvas.min.js';
# document.head.appendChild(s);
# }
# """
# base64Data = driver.execute_script(html2canvas)
#
# time.sleep(2)
# driver.execute_script("""
# // 执行截图(推荐配置高清和跨域支持)
# html2canvas(document.getElementById("ConversationReadingPaneContainer").childNodes[1].childNodes[0], {
# scale: 2, // 2倍分辨率防模糊[7](@ref)
# useCORS: true, // 处理跨域图片[2,8](@ref)
# logging: false // 关闭控制台日志
# }).then(canvas=>{
# const base64=canvas.toDataURL('image/jpeg', 0.85);
# // 转换为 Base64 JPG
# console.log(base64);
# return base64;
# })
# """)
screen_shot(driver) screen_shot(driver)
# print('base64Data',base64Data)
# email_box=driver.find_element(By.ID,':mt')
break break
time.sleep(1) time.sleep(1)
driver.quit()
def run(from_email='',from_title=''):
global driver
options = webdriver.ChromeOptions()
options.add_experimental_option("detach", True)
# 步骤1获取到的User Data路径
options.add_argument(r'--user-data-dir=C:\Users\v_bymyma\AppData\Local\Google\Chrome\User Data\Default')
# 步骤2获取到的--profile-directory值
options.add_argument("--profile-directory=auto_py")
options.add_argument("--disable-web-security")
# driver_path = "C:\\Users\\v_bymyma\PycharmProjects\pythonProject\email\driver\chromedriver.exe"
driver = webdriver.Chrome(options=options)
driver.get('https://outlook.live.com/mail/0/')
mapMSg(from_email,from_title)
time.sleep(3) time.sleep(3)
driver.close() driver.quit()
if __name__ == '__main__': if __name__ == '__main__':
run() run('1432448610@qq.com','字体减半')
\ No newline at end of file \ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册