【Selenium】企业微信实战笔记(浏览器复用、获取cookies的两种方法)

使用remote复用已有的浏览器

作用

  • 不需要重新打开一个页面,在当前的chrome的页面上运行
  • 比如你现在需要测试企业微信登录后的用例,不需要操作登录-添加成员等用例,直接添加成员即可
  • 如果你的用例步骤有1~999,你的问题在555才能复现,我们通过复用,可以直接运行第555的步骤

配置使用

  • 配置chrome的环境变量
  • 关闭全部的chrome
  • 确保任务管理器没有chrome和chromedriver的进程
  • 在cmd输入chrome -remote-debugging-port=9222
  • pycharm的配置的代码如下
from selenium import webdriver
from selenium.webdriver.common.by import By
import pytest

class TestRemote():
    def setup(self):
        #创建一个选项options
        opt=webdriver.ChromeOptions()
        #创建一个远程ip端口9222
        opt.debugger_address="127.0.0.1:9222"
        #把选项应用到Chrome浏览器中
        self.driver=webdriver.Chrome(options=opt)

    def teardown(self):
        self.driver.quit()

    def test(self):
        #打开百度首页,选择搜索框,输入111
        self.driver.find_element(By.CSS_SELECTOR,"#kw").send_keys("111")
  • 运行以上命令,你需要先打开百度首页,运行后就会在百度首页自动输入111了,就表示成功了

配置cookies

作用

  • cookies记录了登录后的信息,下次发送请求就会携带已登录的信息,可以做到免登录
  • 好处是不需要再做一次登录等操作了

一些坑

  • 企业微信是有过期时间expiry的,我们的cookies需要定期更新获取
  • 如果用cookies企业微信提示你在其他地方登录过,请重新更新一下cookies
  • 关闭浏览器后,再启动浏览器去自己企业微信的主页会提醒你要登录,百度说如果cookies包含expiry或者expire等过期时间,关闭浏览器cookies不会失效,但他就是失效了,和chrome无关,感觉是企业微信后台的设置,为了安全性。所以百度的知识是有局限的
  • 老是写错driver.get_cookies(),少了一个s

小知识点

  • json.load和json.dump
import json
#确保a是一个字典,而不是字符串,不然True不会转化成json的ture
a={'a':'b','c':True}
with open("json.json","w") as f:
    #把python的字典转化成json,然后保存到json.json文件中
    #第一个参数a是要传入的json值,第二个参数是文件对象
    json.dump(a,f)

with open("json.json","r") as f:
    #把文件中的json转化成dict类型,第一个参数传文件对象
    #会把json的true转化成dict的True
    b=json.load(f)
    print(b)
  • json.loads和dumps
import json

a={'a':'b','c':True}
#把字典转化成json,dumps是装载到json
print(json.dumps(a))

b='{"a": "b", "c": true}'
#把json转化成字典,loads是加载给python用
print(json.loads(b))
  • List[Dict]
#导入List和Dict
from typing import List, Dict
import json

#a一定是字符串,而且里面内嵌List和Dict
a='[{"a":"b"},{"c":"d"}]'

#固定写法,右边必须是json.loads
#固定写法,左边必须是List[Dict]
b:List[Dict]=json.loads(a)

#好处是可以直接使用list的方法
b.append(1)
  • selenium的cookies不支持expiry,所以遇到要去掉

使用remote复用浏览器的方法获取cookies

  1. 先打开浏览器,打开企业微信登录界面
  2. 用手机扫码登录企业微信
  3. 先运行test_get_cookies获取登录后的cookies
  4. 关闭浏览器
  5. 再运行test_weixin,就可以跑用例了
from typing import List, Dict
from selenium import webdriver
from time import sleep
from selenium.webdriver.common.by import By
import pytest
import json

class TestChains():
    def setup(self):
        #创建一个选项options
        opt=webdriver.ChromeOptions()
        #创建一个远程ip端口9222
        opt.debugger_address="127.0.0.1:1222"


    def teardown(self):
        self.driver.quit()

    def test_get_cookies(self):
        self.driver=webdriver.Chrome(opt)
        #获取当前登录之后的微信页面的cookies
        cookies=self.driver.get_cookies()
        with open("cookies.txt","w") as f:
            #dump方法把cookies存到文件cookies.txt中
            json.dump(cookies,f)
    
    def test_weixin(self):
        self.driver=webdriver.Chrome()
        #先打开企业微信的页面,才能传cookies进去
        self.driver.get("https://work.weixin.qq.com/")
        
        with open("cookies.txt","r") as f:
            #从文件获取cookies,并转化成list对象
            cookies:List[Dict]=json.load(f)
        #遍历每一条cookies,把登录的cookies传入到企业微信中
        for cookie in cookies:
            #由于selenium的cookies不支持expiry,所以需要去掉
            if "expiry" in cookie.keys():
                #dict支持pop的删除函数
                cookie.pop("expiry")
            #添加cookies
            self.driver.add_cookie(cookie)
        #再打开企业微信登录后的页面
        self.driver.get("https://work.weixin.qq.com/wework_admin/frame")
        sleep(5)



使用sleep的方法获取cookies

  1. 运行test_weixin_sleep方法
  2. 手机马上扫码,运行完test_weixin_sleep方法获取cookies
  3. 再运行test_weixin,就可以跑用例了
from typing import List, Dict
from selenium import webdriver
from time import sleep
from selenium.webdriver.common.by import By
import pytest
import json

class TestChains():
    def setup(self):
        self.driver=webdriver.Chrome()

    def teardown(self):
        self.driver.quit()

    def test_weixin_sleep(self):
        self.driver.get("https://work.weixin.qq.com/wework_admin/loginpage_wx?from=myhome")
        sleep(30)
        cookies=self.driver.get_cookies()
        with open("cookies.txt","w") as f:
            json.dump(cookies,f)

        
    def test_weixin(self):
        #先打开企业微信的页面,才能传cookies进去
        self.driver.get("https://work.weixin.qq.com/")
        
        with open("cookies.txt","r") as f:
            #从文件获取cookies,并转化成list对象
            cookies:List[Dict]=json.load(f)
        #遍历每一条cookies,把登录的cookies传入到企业微信中
        for cookie in cookies:
            #由于selenium的cookies不支持expiry,所以需要去掉
            if "expiry" in cookie.keys():
                #dict支持pop的删除函数
                cookie.pop("expiry")
            #添加cookies
            self.driver.add_cookie(cookie)
        #再打开企业微信登录后的页面
        self.driver.get("https://work.weixin.qq.com/wework_admin/frame")
        sleep(5)
6 Likes

整理的不错,学习了~

补充一下,为什么需要打开网页才能传cookies?

这里如果不先打开要访问的网页,会报错selenium.common.exceptions.InvalidCookieDomainException: Message: invalid cookie domain

引用网友的解释

The reason is:

  1. Selenium webdriver init with default url data:.
  2. add_cookie require current url is under the domain pattern of cookie.
  3. data: will not match any cookie domain

So, you get invalid cookie domain error.

翻译一下,就是selenium默认域名是data:,cookies中自带域名,发现当前域名不包含在cookies中时,则cookies设置失败 。

感觉这么做也是有一定道理的,cookies本来就是服务端分发给客户端的用户标识,就算其他域名引用了,也是无效的,不如提前预防。

引用网友帖子来源:

谢谢补充,你的markdown用得真好,谢谢鼓励~

1 Like

在Mac上配置Chrome的环境变量遇到一个小坑,来源于自己对shell的不熟悉。

Chrome 在 Mac 上的路径是 /Applications/Google Chrome.app/Contents/MacOS/Google Chrome

这个路径里面有空格,所以在zsh中配置环境变量时,要么是

PATH=$PATH:/Applications/Google\ Chrome.app/Contents/MacOS

要么是

PATH=$PATH:"/Applications/Google Chrome.app/Contents/MacOS"

就是不能是(这会导致配置失败)

PATH=$PATH:"/Applications/Google\ Chrome.app/Contents/MacOS"
2 Likes
关闭