首页
网络资源
技术分享
云资源
分享你我
行动起来,活在当下
累计撰写
107
篇文章
累计创建
13
个标签
累计收到
0
条评论
栏目
首页
网络资源
技术分享
云资源
目 录
CONTENT
最新文章
python-eel-vite-vue-ts 构建桌面应用
<p>源码地址:<a href="https://github.com/Child-Cheng/python-eel-vite-vue-ts" _src="https://github.com/Child-Cheng/python-eel-vite-vue-ts">https://github.com/Child-Cheng/python-eel-vite-vue-ts</a></p><p>效果图:</p><p><img src="https://www.javalc.com/zb_users/upload/2022/05/202205241450164557089.png" alt="image.png"/></p><!--autointro--><!--95-->
2022-05-24
3
0
0
技术分享
CefSharp (100.0.23)版本编译添加MP4支持、开启ffmpeg支持
<p>发布x64、x86地址:</p><p>链接:https://pan.baidu.com/s/1NvFvEv5L-4U8Ny2Ri7GmiA?pwd=6666 <br/></p><p>提取码:6666</p><p><br/></p><p>源码地址:</p><p><a href="https://drive.google.com/drive/folders/1TPRRrLRtRS6vNhmIBCfAZRIKwhO-DKnW?usp=sharing" _src="https://drive.google.com/drive/folders/1TPRRrLRtRS6vNhmIBCfAZRIKwhO-DKnW?usp=sharing"></a></p><!--autointro--><!--94-->
2022-04-21
5
0
0
技术分享
python selenium 封装使用(处理反爬)
<pre class="brush:python;toolbar:false"># coding=utf-8 """ 此文件为selenium常用方法二次封装文件 """ from selenium import webdriver from selenium.webdriver.chrome.options import Options from selenium.webdriver.common.action_chains import ActionChains # 处理鼠标事件 from selenium.webdriver.support.select import Select # 用于处理下拉框 from selenium.common.exceptions import * # 用于处理异常 from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait # 用于处理元素等待 from PIL import Image, ImageEnhance import pytesseract, re import time from urllib.parse import urlparse import sys class BrowserHelper(object): """ selenium框架的主要类 """ original_window = None def __init__(self, browser='chrome'): """ 运行初始化方法默认chrome,当然,你也可以传入一个其他浏览器名称, """ if browser == "firefox" or browser == "ff": self.driver = webdriver.Firefox() elif browser == "chrome": options = Options(); options.add_argument("--disable-blink-features=AutomationControlled"); options.add_experimental_option("excludeSwitches", ["enable-automation"]); options.add_experimental_option('useAutomationExtension', False); self.driver = webdriver.Chrome(options=options) elif browser == "internet explorer" or browser == "ie": self.driver = webdriver.Ie() elif browser == "opera": self.driver = webdriver.Opera() elif browser == "chrome_headless": options = Options(); options.add_argument('--headless'); options.add_argument("--disable-blink-features=AutomationControlled"); options.add_experimental_option("excludeSwitches", ["enable-automation"]); options.add_experimental_option('useAutomationExtension', False); self.driver = webdriver.Chrome(options=options) elif browser == 'edge': self.driver = webdriver.Edge() else: raise NameError( "找不到 %s 浏览器,你应该从这里面选取一个 'ie', 'ff', 'opera', 'edge', 'chrome' or 'chrome_headless'." % browser) def open(self, url, title='', timeout=10): u"""打开浏览器,并最大化,判断title是否为预期""" self.driver.get(url) self.driver.maximize_window() try: WebDriverWait(self.driver, timeout, 1).until(EC.title_contains(title)) except TimeoutException: print("open %s title error" % url) except Exception as msg: print("Error:%s" % msg) def find_element(self, locator, timeout=10): u"""定位元素,参数locator为原则""" try: element = WebDriverWait(self.driver, timeout, 1).until(EC.presence_of_element_located(locator)) return element except: print("%s 页面未找到元素 %s" % (self, locator)) def find_elements(self, locator, timeout=10): u"""定位一组元素""" elements = WebDriverWait(self.driver, timeout, 1).until(EC.presence_of_all_elements_located(locator)) return elements def element_wait(self, by, value, secs=5): """ 等待元素显示 """ try: if by == "id": WebDriverWait(self.driver, secs, 1).until(EC.presence_of_element_located((By.ID, value))) elif by == "name": WebDriverWait(self.driver, secs, 1).until(EC.presence_of_element_located((By.NAME, value))) elif by == "class": WebDriverWait(self.driver, secs, 1).until(EC.presence_of_element_located((By.CLASS_NAME, value))) elif by == "link_text": WebDriverWait(self.driver, secs, 1).until(EC.presence_of_element_located((By.LINK_TEXT, value))) elif by == "xpath": WebDriverWait(self.driver, secs, 1).until(EC.presence_of_element_located((By.XPATH, value))) elif by == "css": WebDriverWait(self.driver, secs, 1).until(EC.presence_of_element_located((By.CSS_SELECTOR, value))) else: raise NoSuchElementException( "找不到元素,请检查语法或元素") except TimeoutException: print("查找元素超时请检查元素") def get_element(self, css): """ 判断元素定位方式,并返回元素 """ if "=>" not in css: by = "css" # 如果是css的格式是#aaa,所以在此加入判断如果不包含=>就默认是css传给上面的element_wait判断元素是否存在 value = css # wait element. self.element_wait(by, css) else: by = css.split("=>")[0] value = css.split("=>")[1] if by == "" or value == "": raise NameError( "语法错误,参考: 'id=>kw 或 xpath=>//*[@id='kw'].") self.element_wait(by, value) if by == "id": element = self.driver.find_element(By.ID, value) elif by == "name": element = self.driver.find_element(By.NAME, value) elif by == "class": element = self.driver.find_element(By.CLASS_NAME, value) elif by == "link_text": element = self.driver.find_element(By.LINK_TEXT, value) elif by == "xpath": element = self.driver.find_element(By.XPATH, value) # 如果是xpath要以此格式传入xpath=>//*[@id='su'] elif by == "css": element = self.driver.find_element(By.CSS_SELECTOR, value) else: raise NameError( "Please enter the correct targeting elements,'id','name','class','link_text','xpath','css'.") return element def get_elements(self, css): """ 判断元素定位方式,并返回元素 """ if "=>" not in css: by = "css" # 如果是css的格式是#aaa,所以在此加入判断如果不包含=>就默认是css传给上面的element_wait判断元素是否存在 value = css # wait element. self.element_wait(by, css) else: by = css.split("=>")[0] value = css.split("=>")[1] if by == "" or value == "": raise NameError( "语法错误,参考: 'id=>kw 或 xpath=>//*[@id='kw'].") self.element_wait(by, value) if by == "id": element = self.driver.find_elements(By.ID, value) elif by == "name": element = self.driver.find_elements(By.NAME, value) elif by == "class": element = self.driver.find_elements(By.CLASS_NAME, value) elif by == "link_text": element = self.driver.find_elements(By.LINK_TEXT, value) elif by == "xpath": element = self.driver.find_elements(By.XPATH, value) # 如果是xpath要以此格式传入xpath=>//*[@id='su'] elif by == "css": element = self.driver.find_elements(By.CSS_SELECTOR, value) else: raise NameError( "Please enter the correct targeting elements,'id','name','class','link_text','xpath','css'.") return element def click(self, locator): u"""封装点击操作""" element = self.find_element(locator) element.click() def send_key(self, locator, text): u"""发送文本后清除内容""" element = self.find_element(locator) element.clear() element.send_keys(text) def is_text_in_element(self, text, locator, timeout=10): u"""判断是否定位到元素""" try: result = WebDriverWait(self.driver, timeout, 1).until(EC.text_to_be_present_in_element(locator, text)) except TimeoutException: print u"元素未定位到:" + str(locator) return False else: return result def is_title(self, title, timeout=10): u"""判断title完全相等""" result = WebDriverWait(self.driver, timeout, 1).until(EC.title_is(title)) return result def is_title_contains(self, title, timeout=10): u"""判断是否包含title""" result = WebDriverWait(self.driver, timeout, 1).until(EC.title_contains(title)) return result def is_select(self, locator, timeout=10): u"""判断元素是否被选中""" result = WebDriverWait(self.driver, timeout, 1).until(EC.element_located_to_be_selected(locator)) return result def is_select_be(self, locator, timeout=10, selected=True): u"""判断元素的状态""" return WebDriverWait(self.driver, timeout, 1).until(EC.element_located_selection_state_to_be(locator, selected)) def is_alert_present(self, timeout=10): u"""判断页面有无alert弹出框,有alert返回alert,无alert返回FALSE""" try: return WebDriverWait(self.driver, timeout, 1).until(EC.alert_is_present()) except: print "No Alert Present" def is_visibility(self, locator, timeout=10): u"""判断元素是否可见,可见返回本身,不可见返回FALSE""" return WebDriverWait(self.driver, timeout, 1).until(EC.visibility_of_element_located(locator)) def is_invisibility(self, locator, timeout=10): u"""判断元素是否可见,不可见,未找到元素返回True""" return WebDriverWait(self.driver, timeout, 1).until(EC.invisibility_of_element_located(locator)) def is_clickable(self, locator, timeout=10): u"""判断元素是否可以点击,可以点击返回本身,不可点击返回FALSE""" return WebDriverWait(self.driver, timeout, 1).until(EC.element_to_be_clickable(locator)) def is_located(self, locator, timeout=10): u"""判断元素是否定位到(元素不一定是可见),如果定位到返回Element,未定位到返回FALSE""" return WebDriverWait(self.driver, timeout, 1).until(EC.presence_of_element_located(locator)) def move_is_element(self, locator): u"""鼠标悬停操作""" element = self.find_element(locator) ActionChains(self.driver).move_to_element(element).perform() def back(self): u"""返回到旧的窗口""" self.driver.back() def forward(self): u"""前进到新窗口""" self.driver.forward() def close(self): u"""关闭窗口""" self.driver.close() def quit(self): u"""关闭driver和所有窗口""" self.driver.quit() def get_title(self): u"""获取当前窗口的title""" return self.driver.title def get_netloc(self): u"""获取当前窗口的title""" res = urlparse(self.driver.current_url) return res.scheme + "://" + res.netloc def is_netloc(self,url: str) -> bool: res = urlparse(url) if res.netloc == "": return True return False def get_current_url(self): u"""获取当前页面url""" return self.driver.current_url def get_text(self, locator): u"""获取文本内容""" return self.find_element(locator).text def get_browser_log_level(self): u"""获取浏览器错误日志级别""" lists = self.driver.get_log('browser') list_value = [] if lists.__len__() != 0: for dicts in lists: for key, value in dicts.items(): list_value.append(value) if 'SEVERE' in list_value: return "SEVERE" elif 'WARNING' in list_value: return "WARNING" return "SUCCESS" def get_attribute(self, locator, name): u"""获取属性""" return self.find_element(locator).get_attribute(name) def js_execute(self, js): u"""执行js""" return self.driver.execute_script(js) def js_fours_element(self, locator): u"""聚焦元素""" element = self.find_element(locator) self.driver.execute_script("arguments[0].scrollIntoView();", element) def js_scroll_top(self): u"""滑动到页面顶部""" js = "window.scrollTo(0,0)" self.driver.execute_script(js) def js_scroll_end(self): u"""滑动到页面底部""" js = "window.scrollTo(0, document.body.scrollHeight)" self.driver.execute_script(js) def select_by_index(self, locator, index): u"""通过所有index,0开始,定位元素""" element = self.find_element(locator) Select(element).select_by_index(index) def select_by_value(self, locator, value): u"""通过value定位元素""" element = self.find_element(locator) Select(element).select_by_value(value) def select_by_text(self, locator, text): u"""通过text定位元素""" element = self.find_element(locator) Select(element).select_by_visible_text(text) def F5(self): """ 刷新当前页面. 用法: driver.F5() """ self.driver.refresh() def open_new_window(self, css): """ 打开新窗口并切换到新打开的窗口. 用法: 传入一个点击后会跳转的元素 driver.open_new_window("link_text=>注册") """ original_window = self.driver.current_window_handle el = self.get_element(css) el.click() all_handles = self.driver.window_handles for handle in all_handles: if handle != original_window: self.driver.switch_to.window(handle) def get_verify_code(self, locator): u"""获取图片验证码""" # 验证码图片保存地址 screenImg = "D:/image/verifyCode.png" # 浏览器页面截图 self.driver.get_screenshot_as_file(screenImg) # 定位验证码大小 location = self.find_element(locator).location size = self.find_element(locator).size left = location['x'] top = location['y'] right = location['x'] + size['width'] bottom = location['y'] + size['height'] # 从文件读取截图,截取验证码位置再次保存 img = Image.open(screenImg).crop((left, top, right, bottom)) img.convert('L') # 转换模式:L|RGB img = ImageEnhance.Contrast(img) # 增加对比度 img = img.enhance(2.0) # 增加饱和度 img.save(screenImg) # 再次读取验证码 img = Image.open(screenImg) time.sleep(1) code = pytesseract.image_to_string(img) return code def open_tab(self): u"""打开新选项卡并切换到新选项卡""" self.driver.switch_to.new_window('tab') def open_window(self): u"""打开一个新窗口并切换到新窗口""" self.driver.switch_to.new_window('window') def switch_tab_or_window(self,original_window:any): u"""切换回旧选项卡或窗口""" self.driver.switch_to.window(original_window) if __name__ == '__main__': driver = BrowserHelper("chrome"); # 检查是否处理反爬 driver.open("https://bot.sannysoft.com/");</pre><!--autointro--><!--93-->
2022-03-17
3
0
0
技术分享
CefSharp 处理js默认弹窗
<p>新建JsDialogHandler并继承IJsDialogHandler</p><pre class="brush:c#;toolbar:false">public class JsDialogHandler : IJsDialogHandler { public bool OnJSDialog(IWebBrowser browserControl, IBrowser browser, string originUrl, CefJsDialogType dialogType, string messageText, string defaultPromptText, IJsDialogCallback callback, ref bool suppressMessage) { //处理js默认弹窗 callback.Continue(true); return true; } public void OnResetDialogState(IWebBrowser browserControl, IBrowser browser) { } public void OnDialogClosed(IWebBrowser browserControl, IBrowser browser) { } public bool OnBeforeUnloadDialog(IWebBrowser chromiumWebBrowser, IBrowser browser, string messageText, bool isReload, IJsDialogCallback callback) { callback.Continue(true); return true; } }</pre><!--autointro--><!--92-->
2022-03-14
3
0
0
技术分享
Cefsharp 拦截请求响应结果
<p>新建FilterData类</p><pre class="brush:c#;toolbar:false"> public class FilterData : IDisposable { private static ConcurrentDictionary<ulong, MemoryStreamResponseFilter> dataFilters = new(); /// <summary> /// 释放标记 /// </summary> private bool disposed; //private ulong Identifier { get; set; } //private MemoryStreamResponseFilter memory { get; set; } public void AddFilter(ulong Identifier, MemoryStreamResponseFilter memory) { dataFilters.TryAdd(Identifier, memory); } public string GetFilter(ulong Identifier) { dataFilters.TryGetValue(Identifier, out MemoryStreamResponseFilter memory); var data = memory?.DataStr; memory?.Close(); dataFilters.TryRemove(Identifier, out MemoryStreamResponseFilter m); return data; } public void Close(ulong Identifier) { dataFilters.TryGetValue(Identifier, out MemoryStreamResponseFilter memory); memory?.Close(); dataFilters.TryRemove(Identifier, out MemoryStreamResponseFilter m); Dispose(); } /// <summary>执行与释放或重置非托管资源关联的应用程序定义的任务。</summary> public void Dispose() { //必须为true Dispose(true); //通知垃圾回收器不再调用终结器 GC.SuppressFinalize(this); } /// <summary> /// 非密封类可重写的Dispose方法,方便子类继承时可重写 /// </summary> /// <param name="disposing"></param> protected virtual void Dispose(bool disposing) { if (disposed) { return; } //清理托管资源 if (disposing) { dataFilters.Clear(); } //告诉自己已经被释放 disposed = true; } ///// <summary> ///// 为了防止忘记显式的调用Dispose方法 ///// </summary> //~FilterData() //{ // //必须为false // Dispose(false); //} }</pre><!--autointro--><!--91-->
2022-03-10
1
0
0
技术分享
CefSharp 滑动、输入、获取标签位置、点击等封装(支持XPath语法操作)
<pre class="brush:c#;toolbar:false"> /// <summary> /// 组装节点对象 /// </summary> /// <param name="browser"></param> /// <param name="tag"></param> /// <param name="document"></param> /// <returns></returns> public static string AssembleIframeDocument(this IBrowser browser, string tag, string document = "document") { string script = "document.evaluate(\"" + tag.Replace("\"", "'") + "\"," + document + ",null,XPathResult.FIRST_ORDERED_NODE_TYPE,null).singleNodeValue.contentWindow.document"; return script; } /// <summary> /// 组装节点对象 /// </summary> /// <param name="browser"></param> /// <param name="tag"></param> /// <param name="document"></param> /// <returns></returns> public static string AssembleDocument(this IBrowser browser, string tag, string document = "document") { string script = "document.evaluate(\"" + tag.Replace("\"", "'") + "\"," + document + ",null,XPathResult.FIRST_ORDERED_NODE_TYPE,null).singleNodeValue"; return script; } /// <summary> /// 获取元素所在位置 /// </summary> /// <param name="browser">浏览器对象</param> /// <param name="tag">标签(NodeName)</param> /// <param name="document">html文档(xpath才技持)</param> /// <returns></returns> public static BoundingClientRect GetBoundingClientRect(this IBrowser browser, string tag, string document = "document") { var isXPath = Regex.IsMatch(tag, "(^//.*)"); if (isXPath) { string script = "(function(){"; script += "var doc= document.evaluate(\"" + tag.Replace("\"", "'") + "\"," + document + ",null,XPathResult.FIRST_ORDERED_NODE_TYPE,null).singleNodeValue;"; script += @"if(doc != null){ let bntRect = doc.getBoundingClientRect(); let result =JSON.stringify({ x: bntRect.left, y: bntRect.top,r:bntRect.right,b:bntRect.bottom }); return result; }; return null; })()"; Task<JavascriptResponse> result = browser.EvaluateScriptAsync(script); result.Wait();//等待脚本执行完 var response = result.Result; if (response.Success && response.Result == null) return null; if (response.Result == null) return null; BoundingClientRect? bc = JsonSerializer.Deserialize<BoundingClientRect>(response.Result.ToString()); return bc; } else { string script = "(function(){"; script += "var doc = document.querySelector(\"" + tag.Replace("\"", "'") + "\");"; script += @"if(doc!=null){ let bntRect = doc.getBoundingClientRect(); let result =JSON.stringify({ x: bntRect.left, y: bntRect.top,r:bntRect.right,b:bntRect.bottom }); return result; }; return null; })()"; Task<JavascriptResponse> result = browser.EvaluateScriptAsync(script); result.Wait();//等待脚本执行完 var response = result.Result; if (response.Success && response.Result == null) return null; if (response.Result == null) return null; BoundingClientRect? bc = JsonSerializer.Deserialize<BoundingClientRect>(response.Result.ToString()); return bc; } } /// <summary> /// 通过ini指定值获取坐标 /// </summary> /// <param name="browser"></param> /// <param name="key">ini配置文件<k,v> k</param> /// <param name="path">ini配置文件路径</param> /// <returns></returns> public static BoundingClientRect GetPosition(this IBrowser browser, string key, string path, string document = "document") { string tagText = INIHelper.Read("tag", key, path);//@"input[name=pass]"; tagText = string.IsNullOrWhiteSpace(tagText) ? INIHelper.Read("tagXPath", key, path) : tagText; var isLabel = browser.CheckLabel(tagText, document); if (!isLabel) return null; var bc = browser.GetBoundingClientRect(tagText, document);//获取登录按钮位置 if (bc == null) return null; return bc; } /// <summary> /// 模拟点击指定选择符DOM元素 /// </summary> /// <param name="selector">jQuery选择符</param> public static void ClickElement(this IBrowser browser, double? left, double? top, bool isFocusEvent = false) { var host = browser.GetHost(); var x = Convert.ToInt32(left) + 5; var y = Convert.ToInt32(top) + 5; host.SendMouseMoveEvent(x, y, false, CefEventFlags.None);//移动鼠标 Thread.Sleep(50); host.SendMouseClickEvent(x, y, MouseButtonType.Left, false, 1, CefEventFlags.None);//按下鼠标左键 Thread.Sleep(50); host.SendFocusEvent(isFocusEvent); Thread.Sleep(50); host.SendMouseClickEvent(x, y, MouseButtonType.Left, true, 1, CefEventFlags.None);//松开鼠标左键 } /// <summary> /// 全选 /// </summary> /// <param name="browser"></param> /// <param name="left"></param> /// <param name="top"></param> public static void SelectAllKeyEvent(this IBrowser browser) { KeyEvent k = new KeyEvent { WindowsKeyCode = 0x41, // A = 0x41, FocusOnEditableField = true, Modifiers = CefEventFlags.ControlDown, Type = KeyEventType.KeyDown, IsSystemKey = false }; browser.GetHost().SendKeyEvent(k); Thread.Sleep(100); k = new KeyEvent { WindowsKeyCode = 0x41, // A = 0x41, FocusOnEditableField = true, Modifiers = CefEventFlags.ControlDown, Type = KeyEventType.KeyUp, IsSystemKey = false }; browser.GetHost().SendKeyEvent(k); Thread.Sleep(100); } /// <summary> /// 向前删除 /// </summary> /// <param name="browser"></param> public static void BackSpaceKeyEvent(this IBrowser browser) { KeyEvent k = new KeyEvent { WindowsKeyCode = 0x08, // Back = 0x08, FocusOnEditableField = true, Modifiers = CefEventFlags.None, IsSystemKey = false, Type = KeyEventType.KeyDown }; browser.GetHost().SendKeyEvent(k); Thread.Sleep(100); k = new KeyEvent { WindowsKeyCode = 0x08, // Back = 0x08, FocusOnEditableField = true, Modifiers = CefEventFlags.None, IsSystemKey = false, Type = KeyEventType.KeyUp }; browser.GetHost().SendKeyEvent(k); Thread.Sleep(100); } /// <summary> /// 按下回车事件 /// </summary> /// <param name="x"></param> /// <param name="y"></param> public static void HitEnterKeyEvent(this IBrowser browser, double? left, double? top) { KeyEvent k = new KeyEvent { WindowsKeyCode = 0x0D, // Enter FocusOnEditableField = true, IsSystemKey = false, Type = KeyEventType.KeyDown }; browser.GetHost().SendKeyEvent(k); //browser.GetHost().SendFocusEvent(); Thread.Sleep(100); k = new KeyEvent { WindowsKeyCode = 0x0D, // Enter FocusOnEditableField = true, IsSystemKey = false, Type = KeyEventType.KeyUp }; browser.GetHost().SendKeyEvent(k); Thread.Sleep(100); } /// <summary> /// 输入内容 /// </summary> /// <param name="browser"></param> /// <param name="inputString"></param> public static void Input(this IBrowser browser, string inputString) { //var inputString = "CefSharp Was Here!"; var host = browser.GetHost(); foreach (var c in inputString) { host.SendKeyEvent(new KeyEvent { WindowsKeyCode = c, Type = KeyEventType.Char }); } } /// <summary> /// 输入帐号 /// </summary> /// <param name="browser">当前浏览器</param> /// <param name="userName">用户名</param> /// <param name="x">x坐标</param> /// <param name="y">y坐标</param> public static void InputUser(this IBrowser browser, string userName, double? x, double? y) { browser.ClickElement(x, y, true); Thread.Sleep(100); browser.Input(userName);//输入帐号 Thread.Sleep(300); } /// <summary> /// 输入密码 /// </summary> /// <param name="browser"></param> /// <param name="pass"></param> /// <param name="x"></param> /// <param name="y"></param> public static void InputPass(this IBrowser browser, string pass, double? x, double? y) { browser.ClickElement(x, y, true); Thread.Sleep(100); browser.Input(pass);//输入帐号 Thread.Sleep(300); } /// <summary> /// 判断标签是否存在 /// </summary> /// <param name="browser">浏览器对象</param> /// <param name="tag">标签(NodeName)</param> /// <param name="document">html文档(xpath才技持)</param> /// <returns></returns> public static bool IsQuerySelector(this IBrowser browser, string tag, string document = "document") { var isXPath = Regex.IsMatch(tag, "(^//.*)"); if (isXPath) { string script = "(function(){"; script += "var doc= document.evaluate(\"" + tag.Replace("\"", "'") + "\","+ document + ",null,XPathResult.FIRST_ORDERED_NODE_TYPE,null).singleNodeValue;"; script += @"if(doc == null) return null; let result =JSON.stringify({ data:true }); return result; })()"; Task<JavascriptResponse> result = browser.EvaluateScriptAsync(script); result.Wait();//等待脚本执行完 if (result == null) return false; var response = result.Result; if (response.Success && response.Result == null) return false; return true; } else { string script = "(function(){"; script += "var doc = document.querySelector(\"" + tag.Replace("\"", "'") + "\");"; script += @"if(doc==null) return null; let result =JSON.stringify({ data:true }); return result; })()"; Task<JavascriptResponse> result = browser.EvaluateScriptAsync(script); result.Wait(); //等待脚本执行完 var response = result.Result; if (response.Success && response.Result == null) return false; if (response.Result == null) return false; return true; } } /// <summary> /// 发送鼠标滚轮事件 /// </summary> /// <param name="browser">浏览器对象</param> /// <param name="left">x</param> /// <param name="top">y</param> public static void SendMouseWheel(this IBrowser browser, double? left, double? top) { var host = browser.GetHost(); var x = Convert.ToInt32(left) + 5; var y = Convert.ToInt32(top) + 5; host.SendMouseWheelEvent(Convert.ToInt32(0), Convert.ToInt32(top), x, y, CefEventFlags.None); Thread.Sleep(50); host.SendMouseClickEvent(x, y, MouseButtonType.Left, false, 1, CefEventFlags.None);//按下鼠标左键 Thread.Sleep(50); Thread.Sleep(50); host.SendMouseClickEvent(x, y, MouseButtonType.Left, true, 1, CefEventFlags.None);//松开鼠标左键 } /// <summary> /// 滚动到指定元素上 /// </summary> /// <param name="browser">浏览器对象</param> /// <param name="tag">标签(NodeName)</param> /// <param name="document">html文档(xpath才技持)</param> /// <returns></returns> private static bool ScrollIntoView(this IBrowser browser, string tag, string document = "document") { var isXPath = Regex.IsMatch(tag, "(^//.*)"); if (isXPath) { string script = "(function(){"; script += "var doc= document.evaluate(\"" + tag + "\","+ document + ",null,XPathResult.FIRST_ORDERED_NODE_TYPE,null).singleNodeValue;"; script += @"if(doc != null){doc.scrollIntoView({block: 'center',behavior: 'smooth'}); return true}; return false; })()"; Task<JavascriptResponse> result = browser.EvaluateScriptAsync(script); result.Wait();//等待脚本执行完 var response = result.Result; if (response.Success && response.Result == null) return false; if (response.Result == null) return false; var bo = (bool)response.Result; return bo; } else { string script = "(function(){"; script += "var doc = document.querySelector(\"" + tag.Replace("\"", "'") + "\");"; script += @"if(doc != null){doc.scrollIntoView({block: 'center',behavior: 'smooth'}); return true}; return false; })()"; Task<JavascriptResponse> result = browser.EvaluateScriptAsync(script); result.Wait(); //等待脚本执行完 var response = result.Result; if (response.Success && response.Result == null) return false; if (response.Result == null) return false; var bo = (bool)response.Result; return bo; } } /// <summary> /// 滚动到指定元素上 /// </summary> /// <param name="browser"></param> /// <param name="key">ini配置文件<k,v> k</param> /// <param name="path">ini配置文件路径</param> /// <param name="document"></param> /// <returns></returns> public static bool ScrollIntoView(this IBrowser browser, string key, string path, string document = "document") { string tagText = INIHelper.Read("tag", key, path); tagText = string.IsNullOrWhiteSpace(tagText) ? INIHelper.Read("tagXPath", key, path) : tagText; var isLabel = browser.CheckLabel(tagText, document); if (!isLabel) return false; var bc = browser.ScrollIntoView(tagText, document); if (bc == false) return false; return bc; } /// <summary> /// 检查标签是否存在 /// </summary> /// <param name="browser">浏览器对象</param> /// <param name="tag">标签(NodeName)</param> /// <param name="document">html文档(xpath才技持)</param> /// <returns></returns> public static bool CheckLabel(this IBrowser browser, string tag, string document = "document") { var isXPath = Regex.IsMatch(tag, "(^//.*)"); bool isTrue = false; if (isXPath) { isTrue = Policy .Handle<Exception>() .OrResult<bool>(r => r == false) .WaitAndRetry(new[] { TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(2), TimeSpan.FromSeconds(3) }).Execute(() => { return browser.IsQuerySelector(tag, document); }); return isTrue; } else { isTrue = Policy .Handle<Exception>() .OrResult<bool>(r => r == false) .WaitAndRetry(new[] { TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(2), TimeSpan.FromSeconds(3) }).Execute(() => { return browser.IsQuerySelector(tag); }); return isTrue; } } /// <summary> /// 检查标签是否存在 /// </summary> /// <param name="browser">浏览器对象</param> /// <param name="key">ini配置文件<k,v> k</param> /// <param name="path">ini配置文件路径</param> /// <param name="document">html文档(xpath才技持)</param> /// <returns></returns> public static bool CheckLabel(this IBrowser browser, string key, string path, string document = "document") { string tagText = INIHelper.Read("tag", key, path);//@"input[name=pass]"; tagText = string.IsNullOrWhiteSpace(tagText) ? INIHelper.Read("tagXPath", key, path) : tagText; var isXPath = Regex.IsMatch(tagText, "(^//.*)"); bool isTrue = false; if (isXPath) { isTrue = Policy .Handle<Exception>() .OrResult<bool>(r => r == false) .WaitAndRetry(new[] { TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(2), TimeSpan.FromSeconds(3) }).Execute(() => { return browser.IsQuerySelector(tagText, document); }); return isTrue; } else { isTrue = Policy .Handle<Exception>() .OrResult<bool>(r => r == false) .WaitAndRetry(new[] { TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(2), TimeSpan.FromSeconds(3) }).Execute(() => { return browser.IsQuerySelector(tagText); }); return isTrue; } }</pre><!--autointro--><!--90-->
2022-02-24
2
0
0
技术分享
CefSharp Dom操作封装
<p>最近在做使用CefSharp 登录各个平台自动发送文章、新闻等因此有如下封装类:</p><pre class="brush:c#;toolbar:false"> public static class DomHelper { /// <summary> /// 获取元素所在位置 /// </summary> /// <param name="browser"></param> /// <param name="tag"></param> /// <returns></returns> public static BoundingClientRect GetBoundingClientRectAsync(this IBrowser browser, string tag) { string script = "(function(){"; script += "var doc = document.querySelector('" + tag + "');"; script += @"if(doc!=null){ let bntRect = doc.getBoundingClientRect(); let result =JSON.stringify({ x: bntRect.left, y: bntRect.top,r:bntRect.right,b:bntRect.bottom }); return result; }; return null; })()"; Task<JavascriptResponse> result = browser.EvaluateScriptAsync(script); result.Wait();//等待脚本执行完 var response = result.Result; if (response.Success && response.Result == null) return null; if (response.Result == null) return null; BoundingClientRect? bc = JsonSerializer.Deserialize<BoundingClientRect>(response.Result.ToString()); return bc; } /// <summary> /// 通过xpath 语法获取坐标 /// </summary> /// <param name="browser"></param> /// <param name="tag"></param> /// <returns></returns> public static BoundingClientRect GetXPathBoundingClientRect(this IBrowser browser, string tag) { string script = "(function(){"; script += "var doc= document.evaluate(\"" + tag + "\",document,null,XPathResult.FIRST_ORDERED_NODE_TYPE,null).singleNodeValue;"; script += @"if(doc != null){ let bntRect = doc.getBoundingClientRect(); let result =JSON.stringify({ x: bntRect.left, y: bntRect.top,r:bntRect.right,b:bntRect.bottom }); return result; }; return null; })()"; Task<JavascriptResponse> result = browser.EvaluateScriptAsync(script); result.Wait();//等待脚本执行完 if (result == null) return null; var response = result.Result; if (response.Success && response.Result == null) return null; BoundingClientRect? bc = JsonSerializer.Deserialize<BoundingClientRect>(response.Result.ToString()); return bc; } /// <summary> /// 模拟点击指定选择符DOM元素 /// </summary> /// <param name="selector">jQuery选择符</param> public static void ClickElement(this IBrowser browser, double? left, double? top, bool isFocusEvent = false) { var host = browser.GetHost(); var x = Convert.ToInt32(left) + 5; var y = Convert.ToInt32(top) + 5; host.SendMouseMoveEvent(x, y, false, CefEventFlags.None);//移动鼠标 Thread.Sleep(50); host.SendMouseClickEvent(x, y, MouseButtonType.Left, false, 1, CefEventFlags.None);//按下鼠标左键 Thread.Sleep(50); host.SendFocusEvent(isFocusEvent); Thread.Sleep(50); host.SendMouseClickEvent(x, y, MouseButtonType.Left, true, 1, CefEventFlags.None);//松开鼠标左键 } /// <summary> /// 按下回车事件 /// </summary> /// <param name="x"></param> /// <param name="y"></param> public static void HitEnter(this IBrowser browser, int x, int y) { KeyEvent k = new KeyEvent { WindowsKeyCode = 0x0D, // Enter FocusOnEditableField = true, IsSystemKey = false, Type = KeyEventType.KeyDown }; browser.GetHost().SendKeyEvent(k); //browser.GetHost().SendFocusEvent(); Thread.Sleep(100); k = new KeyEvent { WindowsKeyCode = 0x0D, // Enter FocusOnEditableField = true, IsSystemKey = false, Type = KeyEventType.KeyUp }; browser.GetHost().SendKeyEvent(k); Thread.Sleep(100); } /// <summary> /// 输入内容 /// </summary> /// <param name="browser"></param> /// <param name="inputString"></param> public static void Input(this IBrowser browser, string inputString) { //var inputString = "CefSharp Was Here!"; var host = browser.GetHost(); foreach (var c in inputString) { host.SendKeyEvent(new KeyEvent { WindowsKeyCode = c, Type = KeyEventType.Char }); } } /// <summary> /// 输入帐号 /// </summary> /// <param name="browser">当前浏览器</param> /// <param name="userName">用户名</param> /// <param name="x">x坐标</param> /// <param name="y">y坐标</param> public static void InputUser(this IBrowser browser, string userName, double? x, double? y) { browser.ClickElement(x, y, true); Thread.Sleep(100); browser.Input(userName);//输入帐号 Thread.Sleep(300); } /// <summary> /// 输入密码 /// </summary> /// <param name="browser"></param> /// <param name="pass"></param> /// <param name="x"></param> /// <param name="y"></param> public static void InputPass(this IBrowser browser, string pass, double? x, double? y) { browser.ClickElement(x, y, true); Thread.Sleep(100); browser.Input(pass);//输入帐号 Thread.Sleep(300); } /// <summary> /// 判断标签是否存在 /// </summary> /// <param name="browser"></param> /// <param name="tag"></param> public static bool IsQuerySelector(this IBrowser browser, string tag) { string script = "(function(){"; script += "var doc = document.querySelector('" + tag + "');"; script += @"if(doc==null) return null; let bntRect = doc.getBoundingClientRect(); let result =JSON.stringify({ x: bntRect.left, y: bntRect.top,r:bntRect.right,b:bntRect.bottom }); return result; })()"; Task<JavascriptResponse> result = browser.EvaluateScriptAsync(script); result.Wait();//等待脚本执行完 var response = result.Result; if (response.Success && response.Result == null) return false; if (response.Result == null) return false; return true; } /// <summary> /// 通过xpath 语法判断元素是否存在 /// </summary> /// <param name="browser"></param> /// <param name="tag"></param> /// <returns></returns> public static bool IsXPathQuerySelector(this IBrowser browser, string tag) { string script = "(function(){"; script += "var doc= document.evaluate(\"" + tag + "\",document,null,XPathResult.FIRST_ORDERED_NODE_TYPE,null).singleNodeValue;"; script += @"if(doc == null) return null; let bntRect = doc.getBoundingClientRect(); let result =JSON.stringify({ x: bntRect.left, y: bntRect.top,r:bntRect.right,b:bntRect.bottom }); return result; })()"; Task<JavascriptResponse> result = browser.EvaluateScriptAsync(script); result.Wait();//等待脚本执行完 if (result == null) return false; var response = result.Result; if (response.Success && response.Result == null) return false; return true; } /// <summary> /// 发送鼠标滚轮事件 /// </summary> /// <param name="browser"></param> /// <param name="left"></param> /// <param name="top"></param> public static void SendMouseWheel(this IBrowser browser, double? left, double? top) { var host = browser.GetHost(); var x = Convert.ToInt32(left) + 5; var y = Convert.ToInt32(top) + 5; host.SendMouseWheelEvent(Convert.ToInt32(0), Convert.ToInt32(top), x, y, CefEventFlags.None); Thread.Sleep(50); host.SendMouseClickEvent(x, y, MouseButtonType.Left, false, 1, CefEventFlags.None);//按下鼠标左键 Thread.Sleep(50); Thread.Sleep(50); host.SendMouseClickEvent(x, y, MouseButtonType.Left, true, 1, CefEventFlags.None);//松开鼠标左键 } /// <summary> /// 滚动到指定元素上 /// </summary> public static bool ScrollIntoView(this IBrowser browser, string tag) { string script = "(function(){"; script += "var doc= document.evaluate(\"" + tag + "\",document,null,XPathResult.FIRST_ORDERED_NODE_TYPE,null).singleNodeValue;"; script += @"if(doc != null){doc.scrollIntoView({block: 'center',behavior: 'smooth'}); return true}; return false; })()"; Task<JavascriptResponse> result = browser.EvaluateScriptAsync(script); result.Wait();//等待脚本执行完 if (result == null) return false; var response = result.Result; if (response.Success && response.Result == null) return false; var bo = (bool)response.Result; return bo; } }</pre><!--autointro--><!--89-->
2022-02-15
2
0
0
技术分享
cefsharp 模拟点击的坑
<p>网上说的基本都是:</p><pre class="brush:c#;toolbar:false"> host.SendMouseClickEvent(x, y, MouseButtonType.Left, false, 1, CefEventFlags.None);//按下鼠标左键 Thread.Sleep(50); host.SendMouseClickEvent(x, y, MouseButtonType.Left, true, 1, CefEventFlags.None);//松开鼠标左键</pre><!--autointro--><!--88-->
2022-02-11
3
0
0
技术分享
c# 区分虚拟网卡 获取真实网卡信息 判断网卡有线或无线
<pre class="brush:c#;toolbar:false">public void GetPhysicsNetworkAdapterInfo() { ManagementObjectSearcher mos = new ManagementObjectSearcher(@"\\.\ROOT\StandardCimv2", "SELECT * FROM MSFT_NetAdapter WHERE Virtual=False"); ManagementObjectCollection moc = mos.Get(); foreach (ManagementObject mo in moc) { string driverDescription = mo["DriverDescription"]?.ToString(); uint interfaceType = Convert.ToUInt32(mo["InterfaceType"] ?? 0); string macAdddr = mo["PermanentAddress"]?.ToString(); Console.WriteLine("---------------------------------------"); Console.WriteLine($"DriverDescription:{driverDescription}"); Console.WriteLine($"MacAddr:{macAdddr}"); Console.WriteLine($"InterfaceType:{interfaceType}"); } }</pre><!--autointro--><!--87-->
2022-01-06
2
0
0
技术分享
.net core 内置的 System.Text.Json 序列化类型扩展支持
<p>添加以扩展:</p><pre class="brush:c#;toolbar:false">public class TextJsonConverExtension { public static void AddConverters(Microsoft.AspNetCore.Mvc.JsonOptions configure) { //添加支持string转int的操作 configure.JsonSerializerOptions.Converters.Add(new IntToStringConverter()); configure.JsonSerializerOptions.Converters.Add(new StringToStringConverter()); configure.JsonSerializerOptions.Converters.Add(new LongToStringConverter()); } } public class IntToStringConverter : JsonConverter<Int32> { public override Int32 Read(ref System.Text.Json.Utf8JsonReader reader, Type type, System.Text.Json.JsonSerializerOptions options) { if (reader.TokenType == System.Text.Json.JsonTokenType.String) { ReadOnlySpan<byte> span = reader.HasValueSequence ? reader.ValueSequence.ToArray() : reader.ValueSpan; if (System.Buffers.Text.Utf8Parser.TryParse(span, out Int32 number, out int bytesConsumed) && span.Length == bytesConsumed) return number; if (Int32.TryParse(reader.GetString(), out number)) return number; } return reader.GetInt32(); } public override void Write(Utf8JsonWriter writer, Int32 value, JsonSerializerOptions options) { writer.WriteStringValue(value.ToString()); } } public class StringToStringConverter : JsonConverter<String> { public override String Read(ref System.Text.Json.Utf8JsonReader reader, Type type, System.Text.Json.JsonSerializerOptions options) { if (reader.TokenType == System.Text.Json.JsonTokenType.String) { return reader.GetString(); } else if(reader.TokenType == System.Text.Json.JsonTokenType.Number) { ReadOnlySpan<byte> span = reader.HasValueSequence ? reader.ValueSequence.ToArray() : reader.ValueSpan; if (System.Buffers.Text.Utf8Parser.TryParse(span, out Int32 number, out int bytesConsumed) && span.Length == bytesConsumed) return number.ToString(); if (Int32.TryParse(reader.GetString(), out number)) return number.ToString(); } return null; //return reader.GetInt32(); } public override void Write(Utf8JsonWriter writer, String value, JsonSerializerOptions options) { writer.WriteStringValue(value.ToString()); } } public class LongToStringConverter : JsonConverter<long> { public override long Read(ref Utf8JsonReader reader, Type type, JsonSerializerOptions options) { if (reader.TokenType == JsonTokenType.String) { ReadOnlySpan<byte> span = reader.HasValueSequence ? reader.ValueSequence.ToArray() : reader.ValueSpan; if (Utf8Parser.TryParse(span, out long number, out int bytesConsumed) && span.Length == bytesConsumed) return number; if (Int64.TryParse(reader.GetString(), out number)) return number; } return reader.GetInt64(); } public override void Write(Utf8JsonWriter writer, long value, JsonSerializerOptions options) { writer.WriteStringValue(value.ToString()); } }</pre><!--autointro--><!--86-->
2021-12-30
3
0
0
技术分享
1
2
3
4
5
...
11