11-24 4 views
非Windows、Mac OS系统下可能会有字体问题,提前准备好相应的字体,这里以微软雅黑为例
1 2 |
sudo mkdir -p /usr/share/fonts/chinese/TrueType sudo cp ./msyhl.ttc /usr/share/fonts/chinese/TrueType |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 |
#!/usr/bin/env python3 # -*- coding: utf-8 -*- # @Author : Eric Winn # @Email : eng.eric.winn@gmail.com # @Time : 2019/11/24 9:52 AM # @Version : 1.0 # @File : utils # @Software : PyCharm import os import sys import time import uuid from selenium import webdriver from PIL import Image, ImageDraw, ImageFont window_height_js = 'return document.body.scrollHeight' window_width = 1024 MAIN_HOST_NAME = '' OPS_USERNAME = '' OPS_PASSWORD = '' MEDIA_ROOT = '' def makedirs(path): if not os.path.exists(path): os.makedirs(path) def ChromeDriver(): options = webdriver.ChromeOptions() options.add_argument("--headless") options.add_argument('--no-sandbox') options.add_argument('--disable-dev-shm-usage') # 设置页面基调 options.add_argument("--window-size=1376,768") # options.add_argument("--start-maximized") # 导入自定义配置和浏览器驱动 if sys.platform == 'linux': return webdriver.Chrome(options=options) else: return webdriver.Chrome(executable_path='./requirements/chromedriver', options=options) class takeScreenShot: """ 模拟登录,定位截图 :param url: 目标页面URL :param classname: 目标截图区域统一的classname,定位使用 :param pagename: 目标页面名称,会生效到最终图片保存的目录名称 :param kwargs: 模拟登录时定位认证信息输入Form表单的字段位置, 预设submit_position_id,username_position,password_position """ def __init__(self, url, classname, pagename, **kwargs): self.url = url self.classname = classname self.pagename = pagename self.homepage_url = MAIN_HOST_NAME self.username = OPS_USERNAME self.password = OPS_PASSWORD self.submit_position_id = kwargs.get( 'submit_position_id') or '//*[@id="root"]/div/div[2]/div[2]/div/form/div[2]/div/div/span/button' self.username_position = kwargs.get('username_position_id') or 'username' self.password_position = kwargs.get('password_position_id') or 'password' # 浏览器 self.driver = ChromeDriver() def login(self): """ 登录网站 :return: """ self.driver.maximize_window() # 设置等待超时 self.driver.implicitly_wait(3) # 平台首页 self.driver.get(self.homepage_url) try: # 定位登录的输入账号位置 self.elem_user = self.driver.find_element_by_id(self.username_position) self.elem_user.clear() # 输入用户名 self.elem_user.send_keys(self.username) # 定位登录的输入密码位置 self.elem_pass = self.driver.find_element_by_id(self.password_position) self.elem_pass.clear() # 输入密码 self.elem_pass.send_keys(self.password) # 定位登录按钮位置 # elem_login = driver.find_element_by_id('loginButton') self.elem_login = self.driver.find_element_by_xpath(self.submit_position_id) # 点击登录 self.elem_login.click() time.sleep(1) except Exception as e: print(e) def screenshot(self): """ 定位截图 :return: """ # 请求目标页面 print(f'url ===>> {self.url}') self.driver.get(self.url) self.driver.implicitly_wait(60) time.sleep(2) # 获取页面最大高度 window_height = self.driver.execute_script(window_height_js) print(f'window: {window_width}, {window_height}') # 设置窗口大小 self.driver.set_window_size(window_width, window_height) time.sleep(1) # 当前页面的完整截图 screenshot_file_dir = os.path.join(MEDIA_ROOT, 'screentshot', self.pagename, str(time.time()).replace('.', '')) makedirs(screenshot_file_dir) screenshot_file_path = os.path.join(screenshot_file_dir, str(uuid.uuid4())) self.driver.save_screenshot(f'{screenshot_file_path}.png') # 获取目标图片元素列表 elements = self.driver.find_elements_by_class_name(self.classname) # 根据定位逐个获取目标区域位置,参照位置对完整截图进行裁剪 id = 0 for element in elements: try: # 获取单个元素的位置x, y轴 location = element.location print(f'location: {location}') # 获取元素的尺寸 size = element.size print(f'size: {size}') # Mac与Linux下计算单位不同 # 计算截图区域左、上、右、下位置,精确定位 if sys.platform == 'linux': left = location['x'] top = location['y'] - 10 width = size['width'] height = size['height'] + 10 else: left = location['x'] * 2 - 10 top = location['y'] * 2 - 10 width = size['width'] * 2 + 20 height = size['height'] * 2 + 20 right = left + width bottom = top + height # 打开完整图片 im = Image.open(f'{screenshot_file_path}.png') print(f'{left},{top},{right},{bottom}') # 裁剪 im = im.crop((left, top, right, bottom)) # im = im.convert('RGB') # 保存裁剪后的图片 img_file_path = os.path.join(screenshot_file_dir, f'{self.classname}_{id}') im.save(f'{img_file_path}_temp.png') self.watermark_text(f'{img_file_path}_temp.png', f'{img_file_path}.png') except Exception as e: print(e) else: id += 1 self.driver.quit() print(f'images have been saved in {screenshot_file_dir}') return screenshot_file_dir def watermark_text(self, input_image_path, output_image_path, text='www.itnotebooks.com'): """ 为图片添加水印 :param input_image_path: :param output_image_path: :param text: :return: """ photo = Image.open(input_image_path) # 添加画板 drawing = ImageDraw.Draw(photo) x, y = photo.size # 字体 font = ImageFont.truetype("requirements/msyhl.ttc", 12) drawing.text((x - 120, y - 25), text, fill=(0, 0, 0, 50), font=font) photo.save(output_image_path, 'png') |
如果想赏钱,可以用微信扫描下面的二维码,一来能刺激我写博客的欲望,二来好维护云主机的费用; 另外再次标注博客原地址 itnotebooks.com 感谢!
