整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

C井调用Windows API实现自动登录

计初衷:

公司为了便于网络管理,使用了IEEE 802.1X的网络访问控制,这样每次开机需要输入两次登录密码,于是我就研究了一下用C#来帮我输入第二此登录的密码

设计思想:

主要是通过调用Windows API中的一些方法,主要使用的也就是FindWindow,FindWindowEx和SendMessage这三个函数,循环遍历当前的所有窗口,找到目标窗口和进程以后把保存在特定位置的用户名密码以及域信息自动填入输入框中,然后再触发一下button事件,最后程序本身退出。

环境:

在Windows 2000中文版 + sp4,VS.net 2003中文版下开发

在Windows 2000中文版下测试通过

程序截图:

具体设计这个Form的代码就略过不详细说了

为了使用Win32 API,需要先引入下面这个命名空间:

using System.Runtime.InteropServices;

另外还需要用到进程和注册表,所以还需要引入下面的两个命名空间:

using System.Threading;

using Microsoft.Win32;

下面的代码是用来添加对API的引用:

Dll Import#region Dll Import

[DllImport("User32.dll",EntryPoint="FindWindow")]

private static extern IntPtr FindWindow(string lpClassName,

string lpWindowName);

[DllImport("user32.dll",EntryPoint="FindWindowEx")]

private static extern IntPtr FindWindowEx(IntPtr hwndParent,

IntPtr hwndChildAfter, string lpszClass, string lpszWindow);

[DllImport("User32.dll",EntryPoint="SendMessage")]

private static extern int SendMessage(IntPtr hWnd,

int Msg, IntPtr wParam, string lParam);

#endregion

laywright库--->自动写爬虫代码

Playwright--中文网

新一代爬虫利器Playwright——自动写代码

Playwright快速上手指南

Playwright是由微软公司2020年初发布的新一代自动化测试工具,相较于目前最常用的Selenium,它仅用一个API即可自动执行Chromium、Firefox、WebKit等主流浏览器自动化操作。作为针对 Python 语言纯自动化的工具,在回归测试中可更快的实现自动化。

介绍了 Playwright 的用法和部分 api,抓取一个网站主要的操作就是获取 url 地址、参考 post 数据、

request、response、元素,本篇文章都有涉及。还有大量的 api 可以参考官方网站。

  1. 用Python安装使用Playwright

前提:需要 Python 3.7 或更高版本;需要安装hromium、Firefox、WebKit等浏览器和playwright第三方模块。

pip方式:

pip install --upgrade pip pip install playwright playwright install

conda方式:

conda config --add channels conda-forge conda config --add channels microsoft conda install playwright

playwright install

这些命令下载 Playwright 包并为 Chromium、Firefox 和 WebKit 安装浏览器二进制文件。

安装后,您可以import在Python脚本中进行Playwright,并启动 3 个浏览器(chromium、firefox、webkit) 中的任何一个。代码如下:

from playwright.sync_api import sync_playwright

with sync_playwright() as p: browser = p.chromium.launch() page = browser.new_page()

page.goto("http://playwright.dev") print(page.title()) browser.close()

默认情况下,Playwright以无头模式运行浏览器。要查看浏览器 UI,请在启动浏览器时传递

headless=False 标志。您还可以使用 slow_mo 来减慢执行速度。在调试工具部分了解更多信息。

firefox.launch(headless=False, slow_mo=50)

  1. 录制脚本

命令行工具可用于记录用户交互并生成 Python 代码

playwright codegen myie9.com

playwright 在抓取页面的时候是不需要太多写代码的,录制就完事了。首先看看有哪些命令参数:

python -m playwright codegen --help

open page and generate code for user actions

Options:

-o, --output <file name> 将生成的脚本保存到文件

--target <language> 要生成的语言javascript、 test、python、python-async, c#(默认:"python")

-b, --browser <browserType> 要使用的浏览器,cr、chromium、ff、firefox、wk、webkit (默认: "chromium"

--channel <channel> Chromium 分发渠道, "chrome"、"chrome-beta"、 "msedge-dev"等

--color-scheme <scheme> 模拟首选配色方案, "light" or "dark"

--device <deviceName> 模拟设备, 如 "iPhone 11"

--geolocation <coordinates> 指定地理位置坐标, 如 "37.819722,-122.478611"

--ignore-https-errors 忽略http错误

--load-storage <filename> 从文件中加载上下文存储状态, 之前用with --save-storage格式保存的文件

--lang <language> 指定语言/区域设置,如"en-GB"

--proxy-server <proxy> 指定代理服务器,例如 "http://myproxy:3128" 或 "socks5://myproxy:8080"

--proxy-bypass <bypass> 逗号分隔的域名来绕过代理,例如“ .com,chromium.org,. domain. com”

--save-storage <filename> 将上下文存储状态保存在最后, 为以后'with --load-storage'备用

--save-trace <filename> 记录会话的跟踪并将其保存到文件中

--timezone <time zone> 时区模仿,例如“Europe/Rome"

--timeout <timeout> 以毫秒为单位输出playright运行时间(default: "10000")

--user-agent <ua string> 指 定 user agent string

--viewport-size <size> 以像素为单位指定浏览器 viewport size,例如“1280,720”

-h, --help 显示命令的帮助

Examples:

$ codege

$ codegen --target=python

$ codegen -b webkit https://example.com

实例过程:

headless代码

python -m playwright codegen -o D:\playwright_demo.py

注:将脚本文件存放在 D 盘的 playwright_demo.py (代码如下)中。

from playwright.sync_api import Playwright, sync_playwright

def run(playwright: Playwright) -> None:

browser = playwright.chromium.launch(headless=False) context = browser.new_context()

# Open new page

page = context.new_page()

# Close page page.close()

# context.close() browser.close()

with sync_playwright() as playwright: run(playwright)

其中: browser=playwright.chromium.launch(headless=False)

headless 是 False 的时候会出现浏览器,如果是 True 就以没有浏览器的方式启动。

  • page参数

Page就是单独的一个浏览器 tab 标签(第一种)创建

也可以是 a 标签中 target="_blank" 打开的 tab 标签(第二种)创建。

page = context.new_page() # 第一种方法

page.goto("https://www.jd.com/")

with page.expect_popup() as popup_info: # 第二种方法

page click("[aria-label=\"OPPO A96 8+256GB 琉璃幻彩 小星环 呼吸灯 高通八核5G芯片 33W快充 OLED

page3 = popup_info.value

page3.wait_for_load_state() print(page3.title())

page方法

page 有多个常用的方法:on、goto、fill、inner_html、content、query_selector、query_selector_all 等等

goto():用于跳转网址

on():事件的监听,可以用来监听浏览器中发生的任何事件,如:close、console、download、request、response 等等。

用来监听 request 请求,打印出 post 的提交数据和请求地址:

def on_request(request):

print(' start ') print(request.url) print(request.post_data) print(' start ')

def run(playwright: Playwright) -> None:

browser = playwright.chromium.launch(headless=False) context = browser.new_context()

page = context.new_page() # Open new page page.on('request', on_request) page.goto("https://www.baidu.com/") context.close()

browser.close()

用来监听 response 响应,并打印出百度中的 png 结尾的图片:

from playwright.sync_api import Playwright, sync_playwright import time

def on_response(response):

if '.png' in response.url:

with open('D:\image\'+str(int(time.time()))+ '.png', 'wb') as f: f.write(response.body())

def run(playwright: Playwright) -> None:

browser = playwright.chromium.launch(headless=False) context = browser.new_context()

page = context.new_page() # Open new page page.on('response', on_response) page.goto("https://www.baidu.com/")

context.close() browser.close()

fill() 用于填写 input 框,在百度搜索框中写入 111:

page.fill("input[name=\"wd\"]", "111")

inner_html()、content() 获取页面源代码: page.inner_html('//html') page.content()

query_selector 选择一个节点,当匹配到多个节点,只会返回第一个,获取 class='toindex' 的文本:

handle = page.query_selector('.toindex') print(handle.text_content())

query_selector_all 选择所有的节点,获取百度页面上所有 input 的 name: handles = page.query_selector_all('input')

for item in handles:

print(item.get_attribute('name')

选择器

Text选择器

以jd网站为例:下面两行可以选择登录或者注册

page.click("text=你好,请登录") `` page.click("text=免费注册")

text=后面也可以写正则表达式,比如:text=/Log\s*in/i 就可以匹配 Login 或者 log IN

如果不确定是否存在某个 text 也可以使用 :has-text('Log')

  • CSS选择器

CSS 选择器就是使用的默认 CSS 引擎。

Playwright 也自定义了一些伪类::visible、:text、:has 等等。用 id 的方式登录到京东网站:

page.click('#loginsubmit')

根据节点的属性选择:

page.click('[awia-label="搜索"]')

根据CSS和子节点选择

li、img是标签,seckill_mod_googs_link_img是img的class值:

page.click('li:has(img.seckill_mod_goods_link_img)')

  1. XPath

Playwright 支持 XPath 选择元素,自动化录制 python 脚本一般是使用的 text 而不是 Xpath。

page.click("//span[contains(@class, 'spinner loading')]|//div[@id='confirmation']")

  1. N-th

N-th >选择第几个:

点击第一个按钮:

page.click("button >> nth=0")

点击最后一个按钮:

page.click("button >> nth=-1")

如何避免el-form中el-input输入框回车键导致页面刷新的痛点问题

## 引言:问题起源与影响

在使用Element UI进行Web前端开发时,我们经常遇到一个常见的痛点问题:在`el-form`组件中的`el-input`输入框内按回车键时,页面会意外地刷新,这并非预期行为,尤其是在表单填写场景下,用户希望的是提交表单而非刷新整个页面。本文将深入探讨这个问题,并给出详尽的解决方案。

### 段落一:问题现象剖析

问题重现

html
<el-form>
  <el-form-item label="用户名">
    <el-input v-model="username"></el-input>
  </el-form-item>
  <!-- 其他表单元素... -->
</el-form>

在上述代码中,当我们在`el-input`中输入内容并按下回车键时,页面会发生刷新,这主要是因为浏览器默认对`<form>`标签或可输入元素(如`<input>`)的回车键事件处理为提交表单,而提交操作通常会导致页面刷新。

### 段落二:解决思路与方法

阻止默认行为

要解决此问题,我们可以采用两种主要策略:

1.

阻止回车键默认提交行为

javascript
export default {
  methods: {
    preventFormSubmit(e) {
      if (e.keyCode === 13) { // keyCode 13代表回车键
        e.preventDefault(); // 阻止默认提交动作
        // 这里可以添加自定义的回车键触发逻辑,例如提交表单
      }
    }
  },
  mounted() {
    document.addEventListener('keydown', this.preventFormSubmit);
  },
  beforeDestroy() {
    document.removeEventListener('keydown', this.preventFormSubmit);
  }
}

2.

局部处理el-input回车事件

html
<el-form @submit.prevent>
  <el-form-item label="用户名">
    <el-input v-model="username" @keyup.enter.native.prevent></el-input>
  </el-form-item>
  <!-- 其他表单元素... -->
</el-form>

在上述代码中,`.native`修饰符用于监听原生DOM事件,`@keyup.enter.prevent`表示监听输入框的回车键按下事件并阻止其默认行为。

自定义回车键功能

javascript
// 在main.js或者其他全局引入的文件中
Vue.directive('prevent-form-submit', {
  inserted(el, binding, vnode) {
    el.addEventListener('keydown', (e) => {
      if (e.target.tagName === 'INPUT' && e.keyCode === 13) {
        e.preventDefault();
        const form = vnode.context.$refs[binding.value];
        if (form && typeof form.validate === 'function') {
          form.validate((valid) => {
            if (valid) {
              // 触发表单提交逻辑
              form.submit();
            }
          });
        }
      }
    });
  }
});

// 在模板中应用全局指令
<el-form ref="myForm" @submit.prevent v-prevent-form-submit="'myForm'">
  <!-- 表单元素... -->
</el-form>

总结起来,解决`el-form`中`el-input`回车键导致页面刷新的问题,关键在于理解和利用Vue事件系统以及原生DOM事件的处理机制,通过适当的事件监听和阻止默认行为,我们可以轻松定制回车键的行为,提升用户体验,同时避免了不必要的页面刷新。希望本篇文章能帮助开发者更好地掌握这一技巧,并应用于实际项目中。