关于python+selenium+requests在服务器端开发多线程并发程序踩过的一些坑

6 篇文章 1 订阅
3 篇文章 0 订阅

最近因为一个需求,着手开发一款使用selenium+requests进行多线程的测试工具,当然还是基于相对熟悉的python来开发。由于很久没写了,就有很多道理我都懂,一试就出错的问题,前前后后折腾了几天总算是开发完了,这里就把期间遇到的问题做一个记录,希望可以帮助到有同样困惑的同学。

一、服务器端环境配置

1. Ubuntu 20.04配置安装python 3.10并修复pip

这个其实内容不是很难,但无奈网上教程抄来抄去,没有一个真正讲清楚的,在参考了几个教程以及实际测试后,整理操作如下:
目前ubuntu 20.04默认的python版本是3.8,所以我们需要先给系统安装3.10,然后再设置默认python并修复对应的pip,这里参考了这篇文章:在Ubuntu20.04上安装Python3.10以及pip,为了方便我就把命令都直接贴出来,经过实际测试是没有问题的。

# 这里的命令默认是root权限,如果不是请加上sudo运行。

# 添加源
apt install software-properties-common
add-apt-repository ppa:deadsnakes/ppa
apt update

# 安装 
apt install python3.10

# 检查目前系统中的python版本,如果你的系统中默认是python3.9或者其他版本,参照替换这里的3.8即可。
ls -l /usr/bin/python*

# 设置默认python版本,路径可以根据实际情况替换,通常不会变,特别要注意末尾的1和2两个数字别漏了。
update-alternatives --install /usr/bin/python3 python3 /usr/bin/python3.8 1
update-alternatives --install /usr/bin/python3 python3 /usr/bin/python3.10 2
update-alternatives --config python3
# 这个时候在终端中运行python3就可以看到已经切换到了python3.10,如果你想直接使用`python`,可以自行查询如何通过设置alias别名来给命令改名,网上教程很多。

# 此时pip还不是3.10对应的版本,需要进行安装。
apt install python3.10-distutils
curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py
python3 get-pip.py
python3 get-pip.py --user
# 然后检查是否安装成功
pip3 -V
#显示“pip 22.1 from /usr/local/lib/python3.10/dist-packages/pip (python 3.10)”就是可以了。

# 20230304更新:
# 如果出现pip功能异常或者告警的操作,可以按照提示把新版的pip路径加到path里面去:
echo 'export PATH=/home/.../bin:$PATH' >>~/.bashrc
source ~/.bashrc
# 这里的...是你自己的实际路径,bashrc也是看你的系统用的是什么终端。

2. ubuntu 20.04安装chrome浏览器和webdriver

使用selenium需要使用和浏览器对应版本的webdriver,这里我们使用chrome。

# 下载安装chrome浏览器
apt update
wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb
apt install ./google-chrome-stable_current_amd64.deb
# 如果是苹果M系列芯片的虚拟机,可以使用以下替代
sudo apt install chromium-browser

# 查看chrome浏览器版本,比如这里是“Google Chrome 101.0.4951.64”
google-chrome -version

下载chromedriver,官方目录链接chromedriver

二 、关于selenium的一些启动参数的说明

1. 无窗口模式

options.add_argument('--headless')

2. 隐身模式

options.add_argument("--incognito")

3. 无沙箱模式

# 这个是当出现浏览器始终卡在“data:,”的时候使用
options.add_argument("--incognito")

4. 页面加载策略

# 当浏览器打开是,默认是阻塞的,即需要等待页面内容加载完成,包括DOM、js、css、图片等等。driver提供了三种加载策略,none、eager、normal。其中eager是只加载完DOM。
options.page_load_strategy = 'eager'

5. 忽略证书不可信的

# 有时候遇上https证书为不可信的时候,可以忽略证书的安全检查。
options.add_argument('--ignore-certificate-errors')

6. 关于加载等待

# selenium的启动机制是这样的,我们可以在打开页面前设置等待页面加载的时间
# 第一步配置启动参数
options.add_argument('xxxxxxxx')
# 第二步启动浏览器
driver = webdriver.Chrome(chrome_options=options, executable_path=chrome_driver)
# 第三步设置等待时间,单位秒
driver.set_page_load_timeout(25)
# 第四步打开url
driver.get("http://xxxxxxxxxxxxxx")
# 这是如果页面在25秒内没有加载完策略指定的内容,就会报错timeout,所以别忘了加上try...except...

7. 当打开页面遇上alert框

# 类似401认证那种或者其他页面默认弹出来的alert框,需要跳过的话,可以强行确认,不存在就跳过
try:
	driver.switch_to.alert.accept()
except:
	pass

8. 关于selenium使用http还是https

# selenium有点比较麻烦就是你需要自己确定是http还是https,可以用requests来判断,我用了一个简单粗暴的方法
for protocolType in ["http://", "https://"]*3:
	driver.get(protocolType + url.strip())
# 两种协议各试3遍

9. 关于判断网页是否打开

# 首先这里是用seleniunm打开大量网站,所以没法使用特定元素来判断,网上有些教程是用这样的方法,思路是可以打开就是title,但是实际上不管能不能打开都有title,打不开的时候默认title就是url。
driver.title

这里我用了一个判断的办法就是,在加载页面前设置一个启动时间,结束设置一个结束时间,如果有标题或者是加载时间在设置的加载超时时间内,就算是可以打开,虽然不是很严谨,但是误差相对来说小很多,附上简单逻辑代码供参考。

for protocolType in ["http://", "https://"]*3:
	start_time = datetime.datetime.now().timestamp()  # 浏览器启动时间
    try:
	    driver.get(protocolType + url.strip())
        try:
        	driver.switch_to.alert.accept()
        except:
            pass
        end_time = datetime.datetime.now().timestamp()  # 网页加载完成时间
        if driver.title or end_time - start_time < 23:  # 有标题或者小于23秒都算可以打开
            print("打开成功")
            break
        else:
            print("打开失败")
except Exception as e:
        print("打开失败")
        time.sleep(2)
driver.quit()

三、关于测试的时候到底是http还是https

在测试过程中无论是requests还是selenium都面临着同一个问题,就是如何判断网站使用的是http还是https,在实际开发过程中,几乎没有找到一种通用方法可以百分百覆盖的成功判断并打开所有网站,最后我用的策略就是,把所有的情况都试一遍。然后做一个计数器,成功打开加一,否则不加,最后计数不为0即为可以打开,虽然看起来有些啰嗦,但是在网络环境稳定的情况下效果还不错。

# 简单代码逻辑
requests_method = [request_method.http_head,request_method.https_head,request_method.http_get, request_method.https_get] 


success_hit = 0
fail_hit = 0
if r.status_code in success_code:
	success_hit += 1
elif r.status_code in fail_code:
	fail_hit += 1
  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值