Python Notes

我的Python笔记

Posted by Ryan Yim on 2022-03-27
Estimated Reading Time 30 Minutes
Words 6.3k In Total
Viewed Times

Python Notes

Windows 7 pip

Windows 7安装完Python后可能在Script下找不到pip.exe

解决:在验证Python.exe可以正常运行的情况下可以执行python -m ensurepip

Python Package

Beautifulsoup4

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
来源:https://beautifulsoup.readthedocs.io/zh_CN/v4.4.0/#id27

# 安装
pip install beautifulsoup4

from bs4 import BeautifulSoup

soup = BeautifulSoup(open("index.html"))
soup = BeautifulSoup("<html>data</html>")
soup = BeautifulSoup(r.text)

# 找到所有div
soup.find_all("div")

# Tab属性
tab.attrs

# div 类名叫certified-c
soup.findAll("div","certified-c")

# 标签属的id属性为lblStartPlaceAB的文字
soup.find(attrs={"id": "lblStartPlaceAB"}).string

# div类名为div-s的div
soup.find("div","div-s").div

# 标签style属性为color:Black的
soup.find_all(attrs={"style": "color:Black"})

Mkdocs && Mkdocstrings—— 生成Python项目API文档

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
# Install 
pip install mkdocs
pip install mkdocstrings
pip install mkdocstrings-python

# Test install
mkdocs help

# Start
$ mkdocs new my-project
$ cd my-project

# 生成文档
$ mkdocs new "PyDocs"
# 修改配置`mkdocs.yml`
site_name: Python Docs
plugins:
- mkdocstrings
- search

# MD文档:
::: 文件夹.脚本名

最后
$ mkdocs build

Pipreqs —— 自动生成requirements.txt

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
# 自动生成Python项目依赖列表
pip install pipreqs

使用:
$ pipreqs /home/project/location
Successfully saved requirements file in /home/project/location/requirements.txt

Usage:
pipreqs [options] <path>

Options:
--use-local Use ONLY local package info instead of querying PyPI
--pypi-server <url> Use custom PyPi server
--proxy <url> Use Proxy, parameter will be passed to requests library. You can also just set the
environments parameter in your terminal:
$ export HTTP_PROXY="http://10.10.1.10:3128"
$ export HTTPS_PROXY="https://10.10.1.10:1080"
--debug Print debug information
--ignore <dirs>... Ignore extra directories
--encoding <charset> Use encoding parameter for file open
--savepath <file> Save the list of requirements in the given file
--print Output the list of requirements in the standard output
--force Overwrite existing requirements.txt
--diff <file> Compare modules in requirements.txt to project imports.
--clean <file> Clean up requirements.txt by removing modules that are not imported in project.
--no-pin Omit version of output packages.

Pyinstaller —— 打包Python项目

1
2
3
4
5
6
# 打包Python程序
pip3 install pyinstaller
# 打包成一个文件
pyinstaller -F xxx.py
# 打包成一个文件夹,-i是图标
pyinstaller xxx.py -i xxx.ico

Requests

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
# 安装
pip install requests

来源:https://requests.readthedocs.io/zh_CN/latest/user/quickstart.html#id2
import requests

# 获取网页
headers = {'user-agent': 'my-app/0.0.1'}
r = requests.get('https://api.github.com/events',headers = headers)
# 网页源代码
r.text
# 网页编码
r.encoding

# 二进制相应内容
r.content
# 如果是图片:
from PIL import Image
from io import BytesIO
i = Image.open(BytesIO(r.content))

# Json响应数据:
r.json()

# 原始响应内容
r.raw
# <requests.packages.urllib3.response.HTTPResponse object at 0x101194810>
r.raw.read(10)
# '\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\x03'

# 保存文本流到文件
with open(filename, 'wb') as fd:
for chunk in r.iter_content(chunk_size):
fd.write(chunk)

Selenium —— 浏览器自动化

接管已打开的浏览器

Chromium & Chrome——来源

  • 先决条件
  1. Chrome浏览器-版本63或更高版本
  2. 将Chrome浏览器安装目录添加到Path变量中(如果您使用的是Windows)-尽管这不是必需的,但它是可取的,因为它允许使用终端/命令提示符从任何目录打开chrome浏览器。
  3. 将Chrome浏览器设为默认的网络浏览器(可选)–在我们的情况下,这是一个特殊的先决条件,因为只有在Chrome是默认的网络浏览器并且它是唯一运行的chrome实例时,才能在以远程调试模式打开的Chrome浏览器中打开报告。

步骤:

  1. 使用以下命令之一,使用终端/命令提示符以远程调试模式打开新的Chrome浏览器实例。
1
2
3
4
5
6
/*Ubuntu*/
google-chrome --remote-debugging-port=<remote-port>
/*Windows*/
chrome --remote-debugging-port=<remote-port>
/ Mine /
chromium --remote-debugging-port=9222

在这两个命令中,将替换为当前未用于任何其他应用程序的四位数端口号。—可以将user-data-dir =

添加到上述命令的末尾,以使用新的配置文件启动Chrome浏览器。

2.在您喜欢的IDE中导航到您的测试框架,并设置系统属性(在Java中webdriver.chrome.driver指向chrome驱动程序。

例如:

1
2
3
4
/*Ubuntu*/
System.setProperty("webdriver.chrome.driver", "<path-to-chrome-driver>/chromedriver");
/*Windows*/
System.setProperty("webdriver.chrome.driver", "<path-to-chrome-driver>/chromedriver.exe");

3.如下初始化Chrome驱动程序。(示例代码以Java编程语言提供)

1
2
3
ChromeOptions options = new ChromeOptions();
options.setExperimentalOption("debuggerAddress","localhost:<remote-port>");
ChromeDriver driver = new ChromeDriver(options);

很好。您可以使用刚刚初始化的Chrome驱动程序运行自动化测试。

在我们的情况下,在打开Chrome浏览器之后并启动Chrome驱动程序之前,我们在Oracle Forms Application中运行了UI测试,并在打开的Chrome浏览器实例中捕获了生成的报告链接。

测试代码:

1
2
3
4
5
6
7
8
System.setProperty("webdriver.chrome.driver", "D:\\drivers\\chromedriver.exe");
ChromeOptions options = new ChromeOptions();
options.setExperimentalOption("debuggerAddress", "127.0.0.1:9222"); //此处的端口号一定要ChromeDebug模式启动的端口号相同
//否则报错: Exception in thread "main" org.openqa.selenium.WebDriverException: unknown error: cannot connect to chrome at 127.0.0.1:9222
//from chrome not reachable

WebDriver driver = new ChromeDriver(options);
System.out.println(driver.getTitle());
1
2
3
4
5
6
7
8
9
10
11
12
13
14
from selenium import webdriver
from selenium.webdriver.chrome.options import Options

# browser = webdriver.Firefox(executable_path='./geckodriver')
# browser = webdriver.Chrome(executable_path='./chromedriver')

# 最大化浏览器
# browser.maximize_window()

chrome_options = Options()
chrome_options.add_experimental_option("debuggerAddress", "127.0.0.1:9222")
chrome_driver = "./chromedriver"
driver = webdriver.Chrome(executable_path=chrome_driver, chrome_options=chrome_options)
print(driver.title)
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
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
# 安装
pip install -U selenium

# 配置浏览器驱动:
Chrome: https://chromedriver.chromium.org/downloads
Edge: https://developer.microsoft.com/en-us/microsoft-edge/tools/webdriver/
Firefox: https://github.com/mozilla/geckodriver/releases
Safari: https://webkit.org/blog/6900/webdriver-support-in-safari-10/
# 火狐为例:
下载geckodriver-v0.28.0-linux64.tar.gz后解压,然后:
sudo mv geckodriver /usr/local/bin
# 或者
export PATH=$PATH:/opt/WebDriver/bin >> ~/.profile

# e.g. 1
from selenium import webdriver

browser = webdriver.Firefox()
browser.get('https://www.baidu.com')

# e.g.2
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys

browser = webdriver.Firefox()

browser.get('https://www.baidu.com')
assert '百度' in browser.title

elem = browser.find_element(By.NAME, 'wd') # Find the search box
elem.send_keys('seleniumhq' + Keys.RETURN)

browser.quit()

# 句段
# 打开网站
driver.get("https://selenium.dev")
# 获取当前 URL
driver.current_url
# 后退
driver.back()
# 前进
driver.forward()
# 刷新
driver.refresh()
# 获取标题
driver.title
# 每个窗口都有一个唯一的标识符
driver.current_window_handle

----------------------------------------------------------------------------------
# 切换窗口或标签页
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

# 启动驱动程序
with webdriver.Firefox() as driver:
# 打开网址
driver.get("https://seleniumhq.github.io")

# 设置等待
wait = WebDriverWait(driver, 10)

# 存储原始窗口的 ID
original_window = driver.current_window_handle

# 检查一下,我们还没有打开其他的窗口
assert len(driver.window_handles) == 1

# 单击在新窗口中打开的链接
driver.find_element(By.LINK_TEXT, "new window").click()

# 等待新窗口或标签页
wait.until(EC.number_of_windows_to_be(2))

# 循环执行,直到找到一个新的窗口句柄
for window_handle in driver.window_handles:
if window_handle != original_window:
driver.switch_to.window(window_handle)
break

# 等待新标签页完成加载内容
wait.until(EC.title_is("SeleniumHQ Browser Automation"))
----------------------------------------------------------------------------------
# 创建新窗口(或)新标签页并且切换

# 打开新标签页并切换到新标签页
driver.switch_to.new_window('tab')

# 打开一个新窗口并切换到新窗口
driver.switch_to.new_window('window')
----------------------------------------------------------------------------------
# 关闭窗口或标签页

#关闭标签页或窗口
driver.close()

#切回到之前的标签页或窗口
driver.switch_to.window(original_window)
----------------------------------------------------------------------------------
# 在会话结束时退出浏览器,当你完成了浏览器会话,你应该调用 quit 退出,而不是 close 关闭
driver.quit()
# Python 的 WebDriver 现在支持 Python 上下文管理器,当使用 with 关键字时,可以在执行结束时自动退出驱动程序。
with webdriver.Firefox() as driver:
# WebDriver 代码…

# 在此缩进位置后 WebDriver 会自动退出

----------------------------------------------------------------------------------
----------------------------------------------------------------------------------
Frames and Iframes
框架是一种现在已被弃用的方法,用于从同一域中的多个文档构建站点布局。除非你使用的是 HTML5 之前的 webapp,否则你不太可能与他们合作。内嵌框架允许插入来自完全不同领域的文档,并且仍然经常使用
<div id="modal">
<iframe id="buttonframe"name="myframe"src="https://seleniumhq.github.io">
<button>Click here</button>
</iframe>
</div>
# 这不会工作
driver.find_element(By.TAG_NAME, 'button').click()
# 应该这样:
# 存储网页元素
iframe = driver.find_element(By.CSS_SELECTOR, "#modal > iframe")

# 切换到选择的 iframe
driver.switch_to.frame(iframe)

# 单击按钮
driver.find_element(By.TAG_NAME, 'button').click()
----------------------------------------------------------------------------------
使用 name 或 id
如果您的 frame 或 iframe 具有 id 或 name 属性,则可以使用该属性。如果名称或 id 在页面上不是唯一的, 那么将切换到找到的第一个。
# 通过 id 切换框架
driver.switch_to.frame('buttonframe')
# 单击按钮
driver.find_element(By.TAG_NAME, 'button').click()
# 还可以使用frame的索引, 例如可以使用JavaScript中的 window.frames 进行查询.
# 切换到第 2 个框架
driver.switch_to.frame(1)
# 离开框架
# 切回到默认内容
driver.switch_to.default_content()
----------------------------------------------------------------------------------
----------------------------------------------------------------------------------

----------------------------------------------------------------------------------
----------------------------------------------------------------------------------
# 窗口管理
获取浏览器窗口的大小(以像素为单位)

# 分别获取每个尺寸
width = driver.get_window_size().get("width")
height = driver.get_window_size().get("height")

# 或者存储尺寸并在以后查询它们
size = driver.get_window_size()
width1 = size.get("width")
height1 = size.get("height")
----------------------------------------------------------------------------------
# 设置窗口大小
driver.set_window_size(1024, 768)
# 得到窗口的位置

# 分别获取每个尺寸
x = driver.get_window_position().get('x')
y = driver.get_window_position().get('y')

# 或者存储尺寸并在以后查询它们
position = driver.get_window_position()
x1 = position.get('x')
y1 = position.get('y')
----------------------------------------------------------------------------------
# 设置窗口位置

# 将窗口移动到主显示器的左上角
driver.set_window_position(0, 0)

# 最大化窗口
driver.maximize_window()

# 最小化窗口
driver.minimize_window()

# 全屏窗口
driver.fullscreen_window()

# 屏幕截图
from selenium import webdriver
driver = webdriver.Chrome()
# Navigate to url
driver.get("http://www.example.com")
# Returns and base64 encoded string into image
driver.save_screenshot('./image.png')
driver.quit()

# 元素屏幕截图
from selenium import webdriver
from selenium.webdriver.common.by import By
driver = webdriver.Chrome()
# Navigate to url
driver.get("http://www.example.com")
ele = driver.find_element(By.CSS_SELECTOR, 'h1')
# Returns and base64 encoded string into image
ele.screenshot('./image.png')
driver.quit()

# Execute Script:截至20210111,Python用不了
# code sample not available please raise a PR

----------------------------------------------------------------------------------
----------------------------------------------------------------------------------
# 等待
<!doctype html>
<meta charset=utf-8>
<title>Race Condition Example</title>

<script>
var initialised = false;
window.addEventListener("load", function() {
var newElement = document.createElement("p");
newElement.textContent = "Hello from JavaScript!";
document.body.appendChild(newElement);
initialised = true;
});
</script>

driver.navigate("file:///race_condition.html")
el = driver.find_element(By.TAG_NAME, "p")
assert el.text == "Hello from JavaScript!"

# 显示、隐式等待
WebDriverWait(driver, timeout=3).until(some_condition)
driver.implicitly_wait(10)

## Alerts 警告框
# Click the link to activate the alert
driver.find_element(By.LINK_TEXT, "See an example alert").click()
# Wait for the alert to be displayed and store it in a variable
alert = wait.until(expected_conditions.alert_is_present())
# Store the alert text in a variable
text = alert.text
# Press the OK button
alert.accept()

## Confirm 确认框
# Click the link to activate the alert
driver.find_element(By.LINK_TEXT, "See a sample confirm").click()
# Wait for the alert to be displayed
wait.until(expected_conditions.alert_is_present())
# Store the alert in a variable for reuse
alert = driver.switch_to.alert
# Store the alert text in a variable
text = alert.text
# Press the Cancel button
alert.dismiss()

## Prompt 提示框
# Click the link to activate the alert
driver.find_element(By.LINK_TEXT, "See a sample prompt").click()
# Wait for the alert to be displayed
wait.until(expected_conditions.alert_is_present())
# Store the alert in a variable for reuse
alert = Alert(driver)
# Type your message
alert.send_keys("Selenium")
# Press the OK button
alert.accept()

## Http 代理
from selenium import webdriver
PROXY = "<HOST:PORT>"
webdriver.DesiredCapabilities.FIREFOX['proxy'] = {
"httpProxy": PROXY,
"ftpProxy": PROXY,
"sslProxy": PROXY,
"proxyType": "MANUAL",

}
with webdriver.Firefox() as driver:
# Open URL
driver.get("https://selenium.dev")

## 网络元素

from selenium import webdriver
from selenium.webdriver.common.by import By
driver = webdriver.Firefox()
driver.get("http://www.google.com")
# Get search box element from webElement 'q' using Find Element
search_box = driver.find_element(By.NAME, "q")
search_box.send_keys("webdriver")


Find Elements 与"Find Element"相似, 但返回的是匹配WebElement列表. 要使用列表中的特定WebElement, 您需要遍历元素列表以对选定元素执行操作.
from selenium import webdriver
from selenium.webdriver.common.by import By
driver = webdriver.Firefox()
# Navigate to Url
driver.get("https://www.example.com")
# Get all the elements available with tag name 'p'
elements = driver.find_elements(By.TAG_NAME, 'p')
for e in elements:
print(e.text)

Find Element From Element 此方法用于在父元素的上下文中查找子元素. 为此, 父WebElement与"findElement"链接并访问子元素.
from selenium import webdriver
from selenium.webdriver.common.by import By
driver = webdriver.Firefox()
driver.get("http://www.google.com")
search_form = driver.find_element(By.TAG_NAME, "form")
search_box = search_form.find_element(By.NAME, "q")
search_box.send_keys("webdriver")

Find Elements From Element 此方法用于在父元素的上下文中查找匹配子WebElement的列表. 为此, 父WebElement与"findElements"链接并访问子元素.
from selenium import webdriver
from selenium.webdriver.common.by import By
driver = webdriver.Chrome()
driver.get("https://www.example.com")
# Get element with tag name 'div'
element = driver.find_element(By.TAG_NAME, 'div')
# Get all the elements available with tag name 'p'
elements = element.find_elements(By.TAG_NAME, 'p')
for e in elements:
print(e.text)

Get Active Element 此方法用于追溯或查找当前页面上下文中具有焦点的DOM元素.
from selenium import webdriver
from selenium.webdriver.common.by import By
driver = webdriver.Chrome()
driver.get("https://www.google.com")
driver.find_element(By.CSS_SELECTOR, '[name="q"]').send_keys("webElement")
# Get attribute of current active element
attr = driver.switch_to.active_element.get_attribute("title")
print(attr)

Is Element Enabled 此方法用于检查网页上连接的元素是否被启用或禁用. 返回一个布尔值, 如果在当前浏览上下文中启用了连接的元素, 则返回True; 否则返回false .
# Navigate to url
driver.get("http://www.google.com")
# Returns true if element is enabled else returns false
value = driver.find_element(By.NAME, 'btnK').is_enabled()

Is Element Selected 此方法确定是否 已选择 引用的元素. 此方法广泛用于复选框, 单选按钮, 输入元素和选项元素.
返回一个布尔值, 如果在当前浏览上下文中 已选择 引用的元素, 则返回 True, 否则返回 False.
# Navigate to url
driver.get("https://the-internet.herokuapp.com/checkboxes")
# Returns true if element is checked else returns false
value = driver.find_element(By.CSS_SELECTOR, "input[type='checkbox']:first-of-type").is_selected()

Get Element TagName 此方法用于获取在当前浏览上下文中 具有焦点的被引用元素的 TagName .
# Navigate to url
driver.get("https://www.example.com")
# Returns TagName of the element
attr = driver.find_element(By.CSS_SELECTOR, "h1").tag_name

Get Element Rect 用于获取参考元素的尺寸和坐标.
# Navigate to url
driver.get("https://www.example.com")
# Returns height, width, x and y coordinates referenced element
res = driver.find_element(By.CSS_SELECTOR, "h1").rect

获取元素CSS值 获取当前浏览上下文中元素的特定计算样式属性的值.
# Navigate to Url
driver.get('https://www.example.com')
# Retrieves the computed style property 'color' of linktext
cssValue = driver.findElement(By.LINK_TEXT, "More information...").value_of_css_property('color')

获取元素文本 获取特定元素渲染后的文本.
# Navigate to url
driver.get("https://www.example.com")
# Retrieves the text of the element
text = driver.find_element(By.CSS_SELECTOR, "h1").text

## Keyboard
# sendKeys
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
driver = webdriver.Firefox()
# Navigate to url
driver.get("http://www.google.com")
# Enter "webdriver" text and perform "ENTER" keyboard action
driver.find_element(By.NAME, "q").send_keys("webdriver" + Keys.ENTER)

# keyDown
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
driver = webdriver.Chrome()
# Navigate to url
driver.get("http://www.google.com")
# Enter "webdriver" text and perform "ENTER" keyboard action
driver.find_element(By.NAME, "q").send_keys("webdriver" + Keys.ENTER)
# Perform action ctrl + A (modifier CONTROL + Alphabet A) to select the page
webdriver.ActionChains(driver).key_down(Keys.CONTROL).send_keys("a").perform()

# keyUp
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
driver = webdriver.Chrome()
# Navigate to url
driver.get("http://www.google.com")
# Store google search box WebElement
search = driver.find_element(By.NAME, "q")
action = webdriver.ActionChains(driver)
# Enters text "qwerty" with keyDown SHIFT key and after keyUp SHIFT key (QWERTYqwerty)
action.key_down(Keys.SHIFT).send_keys_to_element(search, "qwerty").key_up(Keys.SHIFT).send_keys("qwerty").perform()

# clear
from selenium import webdriver
from selenium.webdriver.common.by import By
driver = webdriver.Chrome()
# Navigate to url
driver.get("http://www.google.com")
# Store 'SearchInput' element
SearchInput = driver.find_element(By.NAME, "q")
SearchInput.send_keys("selenium")
# Clears the entered text
SearchInput.clear()

==================================================================================
在测试中, 您偶尔会需要验证某事物的颜色;问题是网络上的颜色定义不是个常量. 如果有一种简单的方法可以比较颜色的十六进制与RGB呈现, 或者颜色的RGBA与HSLA呈现, 岂不美哉?
from selenium.webdriver.support.color import Color

您现在可以开始创建颜色对象. 每个颜色对象都需要使用您颜色的字符串定义来创建. 支持的颜色定义如下:
HEX_COLOUR = Color.from_string('#2F7ED8')
RGB_COLOUR = Color.from_string('rgb(255, 255, 255)')
RGB_COLOUR = Color.from_string('rgb(40%, 20%, 40%)')
RGBA_COLOUR = Color.from_string('rgba(255, 255, 255, 0.5)')
RGBA_COLOUR = Color.from_string('rgba(40%, 20%, 40%, 0.5)')
HSL_COLOUR = Color.from_string('hsl(100, 0%, 50%)')
HSLA_COLOUR = Color.from_string('hsla(100, 0%, 50%, 0.5)')

Color类还支持在以下网址中指定的所有基本颜色定义 http://www.w3.org/TR/css3-color/#html4.
private final Color BLACK = Color.fromString("black");
private final Color CHOCOLATE = Color.fromString("chocolate");
private final Color HOTPINK = Color.fromString("hotpink");

如果元素上未设置颜色, 则有时浏览器会返回“透明”的颜色值. Color类也支持此功能:
TRANSPARENT = Color.from_string('transparent')

现在, 您可以安全地查询元素以获取其颜色/背景色, 任何响应都将被正确解析并转换为有效的Color对象:
login_button_colour = Color.from_string(driver.find_element(By.ID,'login').value_of_css_property('color'))
login_button_background_colour = Color.from_string(driver.find_element(By.ID,'login').value_of_css_property('background-color'))
然后, 您可以直接比较颜色对象:
assert login_button_background_colour == HOTPINK

## 同选择元素一起工作
选择元素可能需要大量样板代码才能自动化. 为了减少这种情况并使您的测试更干净, 在Selenium的support包中有一个 Select 类. 要使用它,您将需要以下导入语句:
from selenium.webdriver.support.select import Select
然后,您能够参考 <select> 元素,基于WebElement创建一个Select对象。
select_element = driver.find_element(By.ID,'selectElementID')
select_object = Select(select_element)
Select对象现在将为您提供一系列命令,使您可以与 <select> 元素进行交互. 首先,有多种方法可以从 <select> 元素中选择一个选项.
<select>
<option value=value1>Bread</option>
<option value=value2 selected>Milk</option>
<option value=value3>Cheese</option>
</select>

# Select an <option> based upon the <select> element's internal index
select_object.select_by_index(1)
# Select an <option> based upon its value attribute
select_object.select_by_value('value1')
# Select an <option> based upon its text
select_object.select_by_visible_text('Bread')
然后,您可以检视所有被选择的选项:
# Return a list[WebElement] of options that have been selected
all_selected_options = select_object.all_selected_options
# Return a WebElement referencing the first selection option found by walking down the DOM
first_selected_option = select_object.first_selected_option

或者您可能只对 <select> 元素包含哪些 <option> 元素感兴趣:
# Return a list[WebElement] of options that the &lt;select&gt; element contains
all_available_options = select_object.options
如果要取消选择任何元素,现在有四个选项:
# Deselect an <option> based upon the <select> element's internal index
select_object.deselect_by_index(1)
# Deselect an <option> based upon its value attribute
select_object.deselect_by_value('value1')
# Deselect an <option> based upon its text
select_object.deselect_by_visible_text('Bread')
# Deselect all selected <option> elements
select_object.deselect_all()
最后,一些 <select> 元素允许您选择多个选项. 您可以通过使用以下命令确定您的 <select> 元素是否允许多选:
does_this_allow_multiple_selections = select_object.is_multiple

## 鼠标动作详细信息
Mouse表示鼠标事件. 鼠标操作是通过使用底层接口执行的, 其允许我们向Web浏览器提供虚拟化的设备输入操作.

clickAndHold 它将移动到该元素,然后在给定元素的中间单击(不释放).
from selenium import webdriver
driver = webdriver.Chrome()
# Navigate to url
driver.get("http://www.google.com")
# Store 'google search' button web element
searchBtn = driver.find_element(By.LINK_TEXT, "Sign in")
# Perform click-and-hold action on the element
webdriver.ActionChains(driver).click_and_hold(searchBtn).perform()

contextClick
from selenium import webdriver
driver = webdriver.Chrome()
# Navigate to url
driver.get("http://www.google.com")
# Store 'google search' button web element
searchBtn = driver.find_element(By.LINK_TEXT, "Sign in")
# Perform context-click action on the element
webdriver.ActionChains(driver).context_click(searchBtn).perform()

doubleClick
from selenium import webdriver
driver = webdriver.Chrome()
# Navigate to url
driver.get("http://www.google.com")
# Store 'google search' button web element
searchBtn = driver.find_element(By.LINK_TEXT, "Sign in")
# Perform double-click action on the element
webdriver.ActionChains(driver).double_click(searchBtn).perform()

moveToElement
from selenium import webdriver
driver = webdriver.Chrome()
# Navigate to url
driver.get("http://www.google.com")
# Store 'google search' button web element
gmailLink = driver.find_element(By.LINK_TEXT, "Gmail")
# Performs mouse move action onto the element
webdriver.ActionChains(driver).move_to_element(gmailLink).perform()

moveByOffset:
from selenium import webdriver
driver = webdriver.Chrome()
# Navigate to url
driver.get("http://www.google.com")
# Store 'google search' button web element
gmailLink = driver.find_element(By.LINK_TEXT, "Gmail")
#Set x and y offset positions of element
xOffset = 100
yOffset = 100
# Performs mouse move action onto the element
webdriver.ActionChains(driver).move_by_offset(xOffset,yOffset).perform()

dragAndDrop
from selenium import webdriver
driver = webdriver.Chrome()
# Navigate to url
driver.get("https://crossbrowsertesting.github.io/drag-and-drop")
# Store 'box A' as source element
sourceEle = driver.find_element(By.ID, "draggable")
# Store 'box B' as source element
targetEle = driver.find_element(By.ID, "droppable")
# Performs drag and drop action of sourceEle onto the targetEle
webdriver.ActionChains(driver).drag_and_drop(sourceEle,targetEle).perform()

dragAndDropBy
from selenium import webdriver
driver = webdriver.Chrome()
# Navigate to url
driver.get("https://crossbrowsertesting.github.io/drag-and-drop")
# Store 'box A' as source element
sourceEle = driver.find_element(By.ID, "draggable")
# Store 'box B' as source element
targetEle = driver.find_element(By.ID, "droppable")
targetEleXOffset = targetEle.location.get("x")
targetEleYOffset = targetEle.location.get("y")
# Performs dragAndDropBy onto the target element offset position
webdriver.ActionChains(driver).drag_and_drop_by_offset(sourceEle, targetEleXOffset, targetEleYOffset).perform()

release
from selenium import webdriver
driver = webdriver.Chrome()
# Navigate to url
driver.get("https://crossbrowsertesting.github.io/drag-and-drop")
# Store 'box A' as source element
sourceEle = driver.find_element(By.ID, "draggable")
# Store 'box B' as source element
targetEle = driver.find_element(By.ID, "droppable")
# Performs dragAndDropBy onto the target element offset position
webdriver.ActionChains(driver).click_and_hold(sourceEle).move_to_element(targetEle).perform()
#Performs release event
webdriver.ActionChains(driver).release().perform()

## 同cookies一起工作
添加 Cookie
这个方法常常用于将cookie添加到当前访问的上下文中. 添加Cookie仅接受一组已定义的可序列化JSON对象. 这里 是一个链接, 用于描述可接受的JSON键值的列表
首先, 您需要位于有效Cookie的域上. 如果您在开始与网站进行交互之前尝试预设cookie, 并且您的首页很大或需要一段时间才能加载完毕, 则可以选择在网站上找到一个较小的页面 (通常404页很小, 例如 http://example.com/some404page)

from selenium import webdriver
driver = webdriver.Chrome()
driver.get("http://www.example.com")
# Adds the cookie into current browser context
driver.add_cookie({"name": "key", "value": "value"})

获取命名的 Cookie
from selenium import webdriver
driver = webdriver.Chrome()
# Navigate to url
driver.get("http://www.example.com")
# Adds the cookie into current browser context
driver.add_cookie({"name": "foo", "value": "bar"})
# Get cookie details with named cookie 'foo'
print(driver.get_cookie("foo"))

获取全部 Cookies
from selenium import webdriver
driver = webdriver.Chrome()
# Navigate to url
driver.get("http://www.example.com")
driver.add_cookie({"name": "test1", "value": "cookie1"})
driver.add_cookie({"name": "test2", "value": "cookie2"})
# Get all available cookies
print(driver.get_cookies())

删除 Cookie
from selenium import webdriver
driver = webdriver.Chrome()
# Navigate to url
driver.get("http://www.example.com")
driver.add_cookie({"name": "test1", "value": "cookie1"})
driver.add_cookie({"name": "test2", "value": "cookie2"})
# Delete a cookie with name 'test1'
driver.delete_cookie("test1")

删除所有 Cookies
from selenium import webdriver
driver = webdriver.Chrome()
# Navigate to url
driver.get("http://www.example.com")
driver.add_cookie({"name": "test1", "value": "cookie1"})
driver.add_cookie({"name": "test2", "value": "cookie2"})
# Deletes all cookies
driver.delete_all_cookies()

Same-Site Cookie属性
此属性允许用户引导浏览器控制cookie, 是否与第三方站点发起的请求一起发送. 引入其是为了防止CSRF(跨站请求伪造)攻击.
Same-Site cookie属性接受以下两种参数作为指令
Strict:
当sameSite属性设置为 Strict, cookie不会与来自第三方网站的请求一起发送
Lax:
当您将cookie sameSite属性设置为 Lax, cookie将与第三方网站发起的GET请求一起发送.
注意: 到目前为止, 此功能已在Chrome(80+版本), Firefox(79+版本)中提供, 并适用于Selenium 4以及更高版本.
from selenium import webdriver
driver = webdriver.Chrome()
driver.get("http://www.example.com")
# Adds the cookie into current browser context with sameSite 'Strict' (or) 'Lax'
driver.add_cookie({"name": "foo", "value": "value", 'sameSite': 'Strict'})
driver.add_cookie({"name": "foo1", "value": "value", 'sameSite': 'Lax'})
cookie1 = driver.get_cookie('foo')
cookie2 = driver.get_cookie('foo1')
print(cookie1)
print(cookie2)
==================================================================================

XlsxWriter

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
来源:https://xlsxwriter.readthedocs.io/index.html
# 安装
pip install XlsxWriter

import xlsxwriter

# Create a workbook and add a worksheet.
workbook = xlsxwriter.Workbook('Expenses01.xlsx')
worksheet = workbook.add_worksheet()

# Start from the first cell. Rows and columns are zero indexed.
row = 0
col = 0

# Iterate over the data and write it out row by row.
for item, cost in (expenses):
worksheet.write(row, col, item)
worksheet.write(row, col + 1, cost)
row += 1

# Write a total using a formula.
worksheet.write(row, 0, 'Total')
worksheet.write(row, 1, '=SUM(B1:B4)')

# 添加格式
cell_format2 = workbook.add_format(props) # Set properties at creation.
# 分别添加格式
cell_format = workbook.add_format()
cell_format.set_bold()
cell_format.set_font_color('red')

# Add a bold format to use to highlight cells.
bold = workbook.add_format({'bold': 1})

# Add a number format for cells with money.
money_format = workbook.add_format({'num_format': '$#,##0'})

# Add an Excel date format.
date_format = workbook.add_format({'num_format': 'mmmm d yyyy'})

# Adjust the column width.
worksheet.set_column(1, 1, 15)

# Write some data headers.
worksheet.write('A1', 'Item', bold)
worksheet.write('B1', 'Date', bold)
worksheet.write('C1', 'Cost', bold)

# 写入数字
worksheet.write_number('M2',12)

# 其他方法:
write_string()
write_number()
write_blank()
write_formula()
write_datetime()
write_boolean()
write_url()


workbook.close()

You-get —— 视频下载

1
2
3
# 下载Bilibili等网站的视频
pip3 install you-get
you-get 【视频url】

编程类问题

Python类中定义的列表不唯一

解决来源

1
2
3
4
5
6
7
8
class Test:
id = []

# 创建多个实例后,发现更改的id列表是同一个
解决:添加初始化方法,id改为实例参数
class Test:
def __init__(self):
self.id = []

Python时间处理(GTM、UTC)

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
参考:
https://www.cnblogs.com/yuanfang0903/p/11357100.html
https://blog.csdn.net/qq_35462323/article/details/83994563
https://www.cnblogs.com/strivepy/p/10436213.html

字符串时间转datetime:
t_str = "2022-02-18T18:00:00.000+0000"
t_format = '%Y-%m-%dT%H:%M:%S.%f%z'
dt = datetime.datetime.strptime(t_str, t_format)
# 转北京时间(加八小时)
bjt = dt + datetime.timedelta(hours=8)
# 转时间戳(不要加八小时)
ts = dt.timestamp()
# 今天日期(不是时间)
date = datetime.date.today()
# 转为字符串
dt_str = dt.strftime('%Y-%m-%d %H:%M:%S')

# 获取GMT
GMT_FORMAT = '%a, %d %b %Y %H:%M:%S GMT'
#输出: Sun, 27 Mar 2022 04:44:44 GMT
gmt = datetime.datetime.utcnow().strftime(GMT_FORMAT)

GMT_FORMAT的格式索引:
%a 本地的星期缩写
%A 本地的星期全称
%b 本地的月份缩写
%B 本地的月份全称
%c 本地的合适的日期和时间表示形式
%d 月份中的第几天,类型为decimal number(10进制数字),范围[01,31]
%f 微秒,类型为decimal number,范围[0,999999],Python 2.6新增
%H 小时(24进制),类型为decimal number,范围[00,23]
%I 小时(12进制),类型为decimal number,范围[01,12]
%j 一年中的第几天,类型为decimal number,范围[001,366]
%m 月份,类型为decimal number,范围[01,12]
%M 分钟,类型为decimal number,范围[00,59]
%p 本地的上午或下午的表示(AM或PM),只当设置为%I12进制)时才有效
%S 秒钟,类型为decimal number,范围[00,61](6061是为了处理闰秒)
%U 一年中的第几周(以星期日为一周的开始),类型为decimal number,范围[00,53]。在度过新年时,直到一周的全部7天都在该年中时,才计算为第0周。只当指定了年份才有效。
%w 星期,类型为decimal number,范围[0,6],0为星期日
%W 一年中的第几周(以星期一为一周的开始),类型为decimal number,范围[00,53]。在度过新年时,直到一周的全部7天都在该年中时,才计算为第0周。只当指定了年份才有效。
%x 本地的合适的日期表示形式
%X 本地的合适的时间表示形式
%y 去掉世纪的年份数,类型为decimal number,范围[00,99]
%Y 带有世纪的年份数,类型为decimal number
%Z 时区名字(不存在时区时为空)
%% 代表转义的"%"字符

读取文件的第二个for循环不执行

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
with open(FilePath, 'r') as f:
# 首先是核算单张检疫证的总数是否超额
cal_num = 0
cert_num = 0
for line in f:
print(line)
# 这个for循环不会执行
for line in f:
print(line)
原因:已经读取到文末,需要返回开头
解决:
with open(FilePath, 'r') as f:
# 首先是核算单张检疫证的总数是否超额
cal_num = 0
cert_num = 0
for line in f:
print(line)
# 返回开头
f.seek(0)
for line in f:
print(line)

Python: json.decoder.JSONDecodeError: Unexpected UTF-8 BOM (decode using utf-8-sig)

1
2
3
4
5
import json
# 去掉UTF-8 BOM即可
if json_string.startswith(u'\ufeff'):
json_string = json_string.encode('utf8')[3:].decode('utf8')
json_obj = json.loads(json_string)

If you like this blog or find it useful for you, you are welcome to comment on it. You are also welcome to share this blog, so that more people can participate in it. If the images used in the blog infringe your copyright, please contact the author to delete them. Thank you !