2023年2月

创建SM30维护这里就不说了,直接说后续的定制需求的更改
SM30维护自定义表,使用部门一般会有一些需求:

一:输入客户编码后自动带出客户名称、输出物料自动带出物料描述
二:进入维护视图前,对数据进行筛选或排序
三:隐藏删除按钮(或者别的快捷菜单按钮)
四:在维护视图中批量导入/导出数据
五:针对不同操作人员,显示不同的数据
六:输入日期后,根据逻辑自动算出截止日期

一:输入客户编码后自动带出客户名称、输出物料自动带出物料描述 

1、用表格维护事件的方式
SE11->表->菜单->实用程序->表格维护生成器
菜单->环境->修改->事件

新增条目,选定事件编号为05,填写FORM名称:ZMVRPZ_YZ 回车
点击FORM名称右边->编辑器下面的图标创建 include程序:LZPHX_TEXT2F01
在里面写FORM程序:FORM名称要和外面事件上写的一致。

如果报错:函数组 xxxxxxx不能被处理,创建或修改了屏幕没有激活函数组,SE80里面激活该函数组即可。

代码如下:(记得进SE80里面激活维护函数组)

            FORMzmvrpz_yz.SELECT SINGLE maktx FROM makt INTO z_mvrpz-maktxWHERE matnr = z_mvrpz-matnrAND spras = sy-langu.SELECT SINGLE name1 FROM kna1 INTO z_mvrpz-name1WHERE kunnr = z_mvrpz-kunnrAND spras = sy-langu.ENDFORM. 

SAP 报表导出本地文件时报错:

报错文档如下:

Runtime Errors GETWA_NOT_ASSIGNED
Date and Time 2020-10-15 14:59:42

Short text
Field symbol has not yet been assigned.

发生了什么?
Error in the ABAP Application Program

The current ABAP program "SAPLKKBL" had to be terminated because it has
come across a statement that unfortunately cannot be executed.
Note down which actions and inputs caused the error.

To process the problem further, contact you SAP system
administrator.

Using Transaction ST22 for ABAP Dump Analysis, you can look
at and manage termination messages, and you can also
keep them for a long time.

错误分析
You attempted to access an unassigned field symbol
(data segment 136).

This error may occur if
- You address a typed field symbol before it has been set with
ASSIGN
- You address a field symbol that pointed to the line of an
internal table that was deleted
- You address a field symbol that was previously reset using
UNASSIGN or that pointed to a local field that no
longer exists
- You address a global function interface, although the
respective function module is not active - that is, is
not in the list of active calls. The list of active calls
can be taken from this short dump.

经查:有两个原因

1. ALV显示超过了99列,不被支持。
2. ALV字段名错误,定义输出ALV的字段名跟内表定义的字段名不一致。(Fieldcat-fieldname 赋值的时候是小写字母)

我这里的情况是第一种,使用部门导出的是xls格式的Excel文件

 

 然后我用 MHTML 格式导出,发现可以,一百多列也可以导出

问题解决,升级office,导出时选择 Excel(MHTML格式)即可!可以另存为.xlsx格式!。 

我的Office版本是:MS Office 2016专业版

 

强制等待

设置等待最简单的方法就是强制等待,其实就是time.sleep()方法,不管它什么情况,让程序暂停运行一定时间,时间过后继续运行;缺点时不智能,设置的时间太短,元素还没有加载出来,那照样会报错;设置的时间太长,则会浪费时间,不要小瞧每次几秒的时间,case多了,代码量大了,很多个几秒就会影响整体的运行速度了;所以尽量少用这个

隐形等待

driver.implicitly_wait(),隐性等待设置了一个时间,在一段时间内网页是否加载完成,如果完成了,就进行下一步;在设置的时间内没有加载完成,则会报超时加载;

# -*- coding: utf-8 -*-  from selenium import webdriverimport time

driver = webdriver.Chrome()  
driver.implicitly_wait(20) # 隐性等待,最长等30秒  driver.get('https://www.baidu.com')
time.sleep(3)
driver.quit()

 缺点也是不智能,因为随着ajax技术的广泛应用,页面的元素往往都可以时间局部加载,也就是在整个页面没有加载完的时候,可能我们需要的元素已经加载完成了,那就么有必要再等待整个页面的加载,执行进行下一步,而隐性等待满足不了这一点;

  另外一点,隐性等待的设置时全局性的,在开头设置过之后,整个的程序运行过程中都会有效,都会等待页面加载完成;不需要每次设置一遍;

显性等待

WebDriverWait(driver, 20, 0.5).until(expected_conditions.presence_of_element_located(locator)),selenium中的wait模块的WebDriverWait()方法,配合until或者until_not方法,再辅助以一些判断条件,就可以构成这样一个场景:每经过多少秒就查看一次locator的元素是否可见,如果可见就停止等待,如果不可见就继续等待直到超过规定的时间后,报超时异常;当然也可以判断某元素是否在规定时间内不可见等等的各种场景吧,需要根据你自己实际的场景选择判断条件;

# -*- coding: utf-8 -*-  from selenium import webdriver  
from selenium.webdriver.support.wait import WebDriverWait  
from selenium.webdriver.support import expected_conditions as EC  
from selenium.webdriver.common.by import By  
driver = webdriver.Firefox()
driver.get('https://huilansame.github.io')  
WebDriverWait(driver,20,0.5).until(
    EC.presence_of_element_located((By.LINK_TEXT, 'CSDN')))  
print driver.find_element_by_link_text('CSDN').get_attribute('href')
driver.close()

expected_conditions模块中提供了很多可以提供判断的条件:

selenium.webdriver.support.expected_conditions(模块)  

这两个条件类验证title,验证传入的参数title是否等于或包含于driver.title  

title_is  

title_contains  

这两个人条件验证元素是否出现,传入的参数都是元组类型的locator,如(By.ID, 'kw')  

顾名思义,一个只要一个符合条件的元素加载出来就通过;另一个必须所有符合条件的元素都加载出来才行  

presence_of_element_located  

presence_of_all_elements_located  

这三个条件验证元素是否可见,前两个传入参数是元组类型的locator,第三个传入WebElement  

第一个和第三个其实质是一样的  

visibility_of_element_located  

invisibility_of_element_located  

visibility_of  

这两个人条件判断某段文本是否出现在某元素中,一个判断元素的text,一个判断元素的value  

text_to_be_present_in_element  

text_to_be_present_in_element_value  

这个条件判断frame是否可切入,可传入locator元组或者直接传入定位方式:id、name、index或WebElement  

frame_to_be_available_and_switch_to_it  

这个条件判断是否有alert出现  

alert_is_present  

这个条件判断元素是否可点击,传入locator  

element_to_be_clickable  

这四个条件判断元素是否被选中,第一个条件传入WebElement对象,第二个传入locator元组  

第三个传入WebElement对象以及状态,相等返回True,否则返回False  第四个传入locator以及状态,相等返回True,否则返回False  element_to_be_selected  

element_located_to_be_selected  

element_selection_state_to_be  

element_located_selection_state_to_be  

最后一个条件判断一个元素是否仍在DOM中,传入WebElement对象,可以判断页面是否刷新了  

staleness_of

参考链接

工欲善其事,必先利其器!


selenium接管方式

1、指定启动参数打开浏览器

# 指定chrome 远程调试接口与用户目录chrome.exe --remote-debugging-port=9222 --user-data-dir="C:\selenum\AutomationProfile"

2selenium接管

self.options = webdriver.ChromeOptions()
self.options.add_experimental_option("debuggerAddress", "127.0.1:9222")
self.chromeDriver = webdriver.Chrome(driverPath, options=self.options)

chrome远程调试原理分析(CDP协议)

参考链接

https://chromedevtools.github.io/devtools-protocol/

https://chromedevtools.github.io/devtools-protocol/

https://ceshiren.com/t/topic/3567

https://www.daimajiaoliu.com/daima/4eee866b8900402

协议

webdriver协议

使用 DevTools 作为协议客户端

开发者工具前端可以附加到远程运行的 Chrome 实例进行调试。要使此方案正常运行,您应该使用 remote-debugging-port 命令行开关启动您的主机Chrome 实例

chrome.exe --remote-debugging-port=9222

然后,您可以使用不同的用户配置文件启动一个单独的客户端Chrome 实例:

chrome.exe --user-data-dir=<某个目录>

现在,您可以从客户端导航到给定端口并附加到任何发现的选项卡以进行调试:http://localhost:9222

监听协议

这对于理解 DevTools 前端如何使用协议特别方便。您可以在发生时查看所有请求/响应和方法。

协议监视器的屏幕截图

单击 DevTools 右上角的齿轮图标以打开设置面板。选择设置左侧的实验。打开“Protocol Monitor”,然后关闭并重新打开 DevTools。现在单击 ⋮ 菜单图标,选择更多工具,然后选择协议监视器

您还可以使用协议监视器(版本 92.0.4497.0+)发出您自己的命令。如果该命令不需要任何参数,请在“协议监视器”面板底部的提示中键入该命令,然后按 Enter,例如, Page.captureScreenshot。如果命令需要参数,请将它们作为 JSON 提供,例如 {"command":"Page.captureScreenshot","parameters":{"format": "jpeg"}}.

http获取启动信息

GET /json/version

Browser version metadata

{    "Browser": "Chrome/72.0.3601.0",    "Protocol-Version": "1.3",    "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3601.0 Safari/537.36",    "V8-Version": "7.2.233",    "WebKit-Version": "537.36 (@cfede9db1d154de0468cb0538479f34c0755a0f4)",    "webSocketDebuggerUrl": "ws://localhost:9222/devtools/browser/b0b8a4fb-bb17-4359-9533-a8d9f3908bd8"}

GET /json or /json/list

A list of all available websocket targets.

[ {
  "description": "",
  "devtoolsFrontendUrl": "/devtools/inspector.html?ws=localhost:9222/devtools/page/DAB7FB6187B554E10B0BD18821265734",
  "id": "DAB7FB6187B554E10B0BD18821265734",
  "title": "Yahoo",
  "type": "page",
  "url": "https://www.yahoo.com/",
  "webSocketDebuggerUrl": "ws://localhost:9222/devtools/page/DAB7FB6187B554E10B0BD18821265734"} ]

GET /json/protocol/

The current devtools protocol, as JSON:

{
  "domains": [
      {
          "domain": "Accessibility",
          "experimental": true,
          "dependencies": [
              "DOM"
          ],
          "types": [
              {
                  "id": "AXValueType",
                  "description": "Enum of possible property types.",
                  "type": "string",
                  "enum": [
                      "boolean",
                      "tristate",// ...

GET /json/new?{url}

Opens a new tab. Responds with the websocket target data for the new tab.

GET /json/activate/{targetId}

Brings a page into the foreground (activate a tab).

For valid targets, the response is 200: "Target activated". If the target is invalid, the response is 404: "No such target id: {targetId}"

GET /json/close/{targetId}

Closes the target page identified by targetId.

For valid targets, the response is 200: "Target is closing". If the target is invalid, the response is 404: "No such target id: {targetId}"

WebSocket /devtools/page/{targetId}

The WebSocket endpoint for the protocol.

GET /devtools/inspector.html

A copy of the DevTools frontend that ship with Chrome.

远程调试步骤

1、设置远程调试端口

chrome.exe --remote-debugging-port=9222

2、http获取浏览信息

postman    http://localhost:9222/json/version
{    "Browser": "Chrome/91.0.4472.124",    "Protocol-Version": "1.3",    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36",    "V8-Version": "9.1.269.36",    "WebKit-Version": "537.36 (@7345a6d1bfcaff81162a957e9b7d52649fe2ac38)",    "webSocketDebuggerUrl": "ws://localhost:9222/devtools/browser/325848c7-f588-4b2a-8d53-871d0c407498"}

3、ws执行后续命令示例

# 获取sessionidimport websocketimport jsonws = websocket.create_connection("ws://localhost:9222/devtools/browser/325848c7-f588-4b2a-8d53-871d0c407498")cmd = {"id": 100, "method": "Target.attachToTarget", "params": {"targetId":"C6D11457622705623B8F5381612D197D", "flatten":True}}data = json.dumps(cmd, ensure_ascii=False)ws.send(data)while 1:
    result = ws.recv()
    print(result)

4、event示例

import websocketimport jsonws = websocket.create_connection("ws://localhost:9222/devtools/page/7064B86A54979CA238AABB1784858038")cmd = {"id": 1, "method": "Page.enable", "params": {"windowId": 1, "bounds":{

}}}data = json.dumps(cmd, ensure_ascii=False)ws.send(data)while 1:
    result = ws.recv()
    print(result)
E:\Desktop\RPAWork\CBSEditor\branches\develop_v3.0\RpaStudioPublish\public\python\python.exe E:/Desktop/RPAWork/CSEditorPython/trunk/compentsAdministration/2.py
{"id":1,"result":{}}
{"method":"Page.frameStartedLoading","params":{"frameId":"7064B86A54979CA238AABB1784858038"}}
{"method":"Page.frameDetached","params":{"frameId":"A099BBAD2608A370D9C76CA5479B5621","reason":"remove"}}
{"method":"Page.frameNavigated","params":{"frame":{"id":"7064B86A54979CA238AABB1784858038","loaderId":"95332EA5BBB3B9346ED939DB007F59D0","url":"https://fanyi.baidu.com/","urlFragment":"#en/zh/Types","domainAndRegistry":"baidu.com","securityOrigin":"https://fanyi.baidu.com","mimeType":"text/html","adFrameType":"none","secureContextType":"Secure","crossOriginIsolatedContextType":"NotIsolated","gatedAPIFeatures":["SharedArrayBuffersTransferAllowed"]}}}
{"method":"Page.frameAttached","params":{"frameId":"CAC1E51A034347E0CD90FAC57B040682","parentFrameId":"7064B86A54979CA238AABB1784858038"}}
{"method":"Page.frameStartedLoading","params":{"frameId":"CAC1E51A034347E0CD90FAC57B040682"}}
{"method":"Page.frameNavigated","params":{"frame":{"id":"CAC1E51A034347E0CD90FAC57B040682","parentId":"7064B86A54979CA238AABB1784858038","loaderId":"62CC3D0059086BA4A88DB784C824BFD6","name":"doc-view-iframe","url":"about:blank","domainAndRegistry":"","securityOrigin":"://","mimeType":"text/html","adFrameType":"none","secureContextType":"Secure","crossOriginIsolatedContextType":"NotIsolated","gatedAPIFeatures":["SharedArrayBuffersTransferAllowed"]}}}
{"method":"Page.frameStoppedLoading","params":{"frameId":"CAC1E51A034347E0CD90FAC57B040682"}}
{"method":"Page.domContentEventFired","params":{"timestamp":873617.921655}}
{"method":"Page.frameAttached","params":{"frameId":"E4F8EB74C7D088A7D98D9F2B6C02F25C","parentFrameId":"7064B86A54979CA238AABB1784858038","stack":{"callFrames":[{"functionName":"qL","scriptId":"280","url":"https://dlswbr.baidu.com/heicha/mw/abclite-2008-s.js","lineNumber":0,"columnNumber":89227},{"functionName":"cf","scriptId":"280","url":"https://dlswbr.baidu.com/heicha/mw/abclite-2008-s.js","lineNumber":0,"columnNumber":108246},{"functionName":"yk","scriptId":"280","url":"https://dlswbr.baidu.com/heicha/mw/abclite-2008-s.js","lineNumber":0,"columnNumber":108414},{"functionName":"ck","scriptId":"280","url":"https://dlswbr.baidu.com/heicha/mw/abclite-2008-s.js","lineNumber":0,"columnNumber":128015},{"functionName":"GZ.<computed>.<computed>","scriptId":"280","url":"https://dlswbr.baidu.com/heicha/mw/abclite-2008-s.js","lineNumber":0,"columnNumber":128242},{"functionName":"N5","scriptId":"280","url":"https://dlswbr.baidu.com/heicha/mw/abclite-2008-s.js","lineNumber":0,"columnNumber":138720},{"functionName":"y","scriptId":"280","url":"https://dlswbr.baidu.com/heicha/mw/abclite-2008-s.js","lineNumber":0,"columnNumber":39001},{"functionName":"","scriptId":"280","url":"https://dlswbr.baidu.com/heicha/mw/abclite-2008-s.js","lineNumber":0,"columnNumber":138980},{"functionName":"_iwWM","scriptId":"280","url":"https://dlswbr.baidu.com/heicha/mw/abclite-2008-s.js","lineNumber":0,"columnNumber":138987},{"functionName":"","scriptId":"280","url":"https://dlswbr.baidu.com/heicha/mw/abclite-2008-s.js","lineNumber":0,"columnNumber":138992}]}}}
{"method":"Page.frameStartedLoading","params":{"frameId":"E4F8EB74C7D088A7D98D9F2B6C02F25C"}}
{"method":"Page.frameStoppedLoading","params":{"frameId":"E4F8EB74C7D088A7D98D9F2B6C02F25C"}}
{"method":"Page.frameDetached","params":{"frameId":"E4F8EB74C7D088A7D98D9F2B6C02F25C","reason":"remove"}}
{"method":"Page.frameAttached","params":{"frameId":"A85725E42A62F74C9D8873D8F81AD2BA","parentFrameId":"7064B86A54979CA238AABB1784858038","stack":{"callFrames":[{"functionName":"ix","scriptId":"318","url":"https://dlswbr.baidu.com/heicha/mw/abclite-2060-s.js?v=0.14359652757150543","lineNumber":1,"columnNumber":62835},{"functionName":"aY","scriptId":"318","url":"https://dlswbr.baidu.com/heicha/mw/abclite-2060-s.js?v=0.14359652757150543","lineNumber":1,"columnNumber":100587},{"functionName":"","scriptId":"318","url":"https://dlswbr.baidu.com/heicha/mw/abclite-2060-s.js?v=0.14359652757150543","lineNumber":1,"columnNumber":101855},{"functionName":"xx.<computed>","scriptId":"318","url":"https://dlswbr.baidu.com/heicha/mw/abclite-2060-s.js?v=0.14359652757150543","lineNumber":1,"columnNumber":109310},{"functionName":"v1","scriptId":"318","url":"https://dlswbr.baidu.com/heicha/mw/abclite-2060-s.js?v=0.14359652757150543","lineNumber":1,"columnNumber":101811},{"functionName":"vW","scriptId":"318","url":"https://dlswbr.baidu.com/heicha/mw/abclite-2060-s.js?v=0.14359652757150543","lineNumber":1,"columnNumber":102541},{"functionName":"p","scriptId":"318","url":"https://dlswbr.baidu.com/heicha/mw/abclite-2060-s.js?v=0.14359652757150543","lineNumber":1,"columnNumber":144953},{"functionName":"Me.<computed>.<computed>","scriptId":"318","url":"https://dlswbr.baidu.com/heicha/mw/abclite-2060-s.js?v=0.14359652757150543","lineNumber":1,"columnNumber":145288},{"functionName":"PN","scriptId":"318","url":"https://dlswbr.baidu.com/heicha/mw/abclite-2060-s.js?v=0.14359652757150543","lineNumber":1,"columnNumber":147945},{"functionName":"D","scriptId":"318","url":"https://dlswbr.baidu.com/heicha/mw/abclite-2060-s.js?v=0.14359652757150543","lineNumber":1,"columnNumber":41294},{"functionName":"","scriptId":"318","url":"https://dlswbr.baidu.com/heicha/mw/abclite-2060-s.js?v=0.14359652757150543","lineNumber":1,"columnNumber":148232},{"functionName":"_3Ku4","scriptId":"318","url":"https://dlswbr.baidu.com/heicha/mw/abclite-2060-s.js?v=0.14359652757150543","lineNumber":1,"columnNumber":148242},{"functionName":"","scriptId":"318","url":"https://dlswbr.baidu.com/heicha/mw/abclite-2060-s.js?v=0.14359652757150543","lineNumber":1,"columnNumber":148247}]}}}
{"method":"Page.frameStartedLoading","params":{"frameId":"A85725E42A62F74C9D8873D8F81AD2BA"}}
{"method":"Page.frameStoppedLoading","params":{"frameId":"A85725E42A62F74C9D8873D8F81AD2BA"}}
{"method":"Page.frameDetached","params":{"frameId":"A85725E42A62F74C9D8873D8F81AD2BA","reason":"remove"}}
{"method":"Page.loadEventFired","params":{"timestamp":873623.526458}}
{"method":"Page.frameStoppedLoading","params":{"frameId":"7064B86A54979CA238AABB1784858038"}}

工欲善其事,必先利其器!


ChromeDevTools协议简称CDP,它允许对Chromium,Chrome和其他基于Blink的浏览器进行检测,探测,调试和配置。许多现有项目目前使用该协议。 Chrome的开发者工具就是使用此协议,该团队也负责维护其API。Chrome浏览器可以远程调试的方式启动, 实际上在浏览器内部启动了一个用DevTools的服务器, 任何符合该协议的websoket通讯都可以被Chrome响应,这样你可以向Chrome发送命令, 执行操作, 实现一些自动化浏览器的操作。大名鼎鼎的ChromeDriver就是通过 DevTools Protocol实现与chrome浏览器进行交互的。

CDP官方文档如下:

https://chromedevtools.github.io/devtools-protocol/

01协议基础

当使用--remote-debugging-port= 0参数启动Chromium/Chrome时,它启动Chrome DevTools协议服务器并将其WebSocket URL打印到STDERR。输出看起来像这样:DevTools listening on ws://127.0.0.1:36775/devtools/browser/a292f96c-7332-4ce8-82a9-7411f3bd280a

客户端可以创建WebSocket以连接到该URL并开始发送CDP命令。 ChromeDevTools协议主要基于JSONRPC:每个命令都是一个带有id/方法和可选参数的JavaScript结构。我们可以用如下js代码,通过websocket协议完成与浏览器的交互

此脚本通过DevTools协议发送Targets.setDiscoverTargets命令。浏览器将首先为每个现有目标发出一个Target.targetCreated事件,然后响应该命令:

connected!

Sending Target.setDiscoverTargets

{"method":"Target.targetCreated","params":{"targetInfo":{"targetId":"38666666cfe-5ef3-44a5-a4e9-024ee6ebde5f","type":"browser","title":"","url":"","attached":true}}}

{"method":"Target.targetCreated","params":{"targetInfo":{"targetId":"52CA0FEA80FB0B98BCDB759E535B21E4","type":"page","title":"","url":"about:blank","attached":false,"browserContextId":"339D5F1CCABEFE8545E15F3C2FA5F505"}}}

{"id":1,"result":{}}

模拟chromedriver实现方案具体流程如下:

02环境搭建

从上面的例子中通过websocket与chrome直接交互实现是比较复杂的,因此各种主流语言都提供了类库来简化该过程,详细信息请参考:

https://github.com/ChromeDevTools/awesome-chrome-devtools#chrome-devtools-protocol

在这里我们使用python的pychrome 来实现与chrome的交互,也可以理解我们自己开发了一个chromedriver!

Pychrome详情请参考:https://github.com/fate0/pychrome

安装pychrome

pip install -U pychrome

03Selenium实现场景回顾

实现场景:在百度输入框中搜索selenium。

我们先回顾一下Selenium的代码实现过程如下:

1.把chromedriver.exe放到系统环境变量中

2.编写py代码

from selenium import webdriver

import unittest

class UntitledTestCase(unittest.TestCase):

def setUp(self):

self.driver = webdriver.Chrome()

self.driver.implicitly_wait(30)

def test_untitled_test_case(self):

driver =self.driver

driver.get("https://www.baidu.com/")

driver.find_element_by_id("kw").clear()

driver.find_element_by_id("kw").send_keys("selenium")

driver.find_element_by_id("su").click()

def tearDown(self):

self.driver.quit()

3.执行自动化脚本

Selenium的原理如下:

从上图可知,最后是通过chromedriver完成了和chrome浏览器的交互!

关于selenium的详细原理分析可以参考文章:Selenium原理精讲

04cdp实现场景

接下来我们通过cdp直接跟chrome浏览器的交互,模拟chromedriver,代码如下:

import pychrome

browser = pychrome.Browser(

url="http://127.0.0.1:9222")

#打开一个新的浏览器tabtab = browser.new_tab()

tab.start()

tab.Network.enable()

#访问baidu

tab.Page.navigate(url="https://www.baidu.com", _timeout=5)

tab.wait(5)

#在搜索框中输入selenium

tab.Runtime.evaluate(expression='document.getElementById("kw").value="selenium"')

tab.wait(1)

#点击‘百度一下’按钮

tab.Runtime.evaluate(expression='document.getElementById("su").click()')

tab.wait(5)

tab.stop()

browser.close_tab(tab)

执行代码前,必须设置chrome属性,如下图所示:

接下来启动chrome。

最后执行py脚本,大家可以看到:

浏览器自动打开新的tab页>在百度输入框中搜索selenium>关闭tab页这一过程!这也就是selenium操控浏览器的原理了!

原创不易,如果文章帮到了你,欢迎转发,让更多的朋友受益!