前言
前面做了一个自动打卡的小程序,基本可以实现上班签到,下班签退的任务,但还是有一些限制的,比如程序需要时时刻刻的运行在电脑上(可以在下班的时候将程序跑起来,但是电脑不能关机),这个问题对我来说其实还好,因为我下班本来就不关电脑。另外一个比较重要的限制就是,很多时候由于网络等等莫名其妙的问题,很容易导致程序终止,总不能把每一行代码都try一下吧,如果程序崩了,打卡失败,而睡梦中的我完全不知情,等到早上慢慢悠悠的过来之后,发现超时了,到时候就很尴尬了。
于是,我继续用selenium做了一个打卡之后,将打卡结果通过服务器发送给手机端,这样我就能提前知道打卡的结果,如果程序崩了,那就做好早睡早起的准备。
思路有了,服务器到哪里去搞?原本的想法是通过python调用微信QQ之类的,但是公司主机权限的问题,程序是跑在Ubuntu虚拟机里面的,搞起来很麻烦。思前想后,既然还是selenium,既然还是网页端,那干脆蹭一蹭CSDN的服务器吧,嘿嘿嘿。
一、Python+Selenium
具体的环境配置可以参考之前的文章。
二、通信环境(服务器、客户端)
手机上的客户端,下载CSDN客户端,登录马甲小号,作为接收信息的载体,早上起来看看私信的消息,就知道有没有打卡成功了。这波啊,这波是给CSDN客户端做宣传。。。
网页端,还是之前的流程,只不过在打卡成功或者失败之后,继续通过selenium登录CSDN账号,通过私信将打卡结果发送给马甲小号。
程序的具体流程如下:
1. selenium借助cookie网页登录csdn
因为网页登录csdn的时候,需要扫码啊,账号啊之类的,十分麻烦,还容易出错,所以就借助cookie的方式来登录,首先是手动登录,然后通过代码获取cookie,保存至本地文件,下次登录的时候直接读取本地文件的cookie信息。
获取cookie代码如下:
import time
import json
from selenium import webdriver
#手动获取cookies
driver = webdriver.Firefox()
url = 'https://blog.csdn.net/qq_34935373/article/details/121680879?spm=1001.2014.3001.5502'
driver.get(url)
a = input("input:")
#获取cookie
cookies = driver.get_cookies()
#cookie保存到cookies.txt文件
f1 = open("cookies.txt","w")
f1.write(json.dumps(cookies))
f1.close
print(cookies)
print(type(cookies))
首先运行程序,代码会自动打开csdn网站的登录页面,此时程序会卡在input输入这里,你只需要扫码登录之后,刷新一下,保证账号已经登录成功了,然后在中断中输入一个字符并enter(让程序执行到input之后),程序就会自动将cookie保存到本地文件了,注意使用的时候,cookie和代码程序放在同一个目录里面。
2.私信发送消息流程
- 打开特定的网页(要和获取cookie的网址保持一致,避免域信息发生改变)
- 读取本地cookie,刷新一下,使得cookie生效
- 模拟点击私信
- 模拟发送打卡信息给马甲小号
- 完成任务,关闭浏览器
代码如下:
# 要先获取cookie,我已经获取过了,注意在哪个网址获取的cookie,就只能在哪个网站用
print("将打卡结果通过服务器发送至手机。。。")
# 登录CSDN
options2 = webdriver.FirefoxOptions()
options2.add_argument("--headless")
options2.add_argument("--disable-gpu")
profile = webdriver.FirefoxProfile()
browser2 = webdriver.Firefox(options=options2,firefox_profile=profile)
# browser2 = webdriver.Firefox()
csdn = LoginUrl(browser2, 'https://blog.csdn.net/qq_34935373/article/details/121680879?spm=1001.2014.3001.5502', u" ", u" ")
csdn.openwebsite()
#从cookies.txt文件读取cookies
f2 = open("cookies.txt")
cookies = json.loads(f2.read())
#使用cookies登录
for cook in cookies:
browser2.add_cookie(cook)
#刷新页面
print("刷新页面通过cookie登陆。。。")
browser2.refresh()
time.sleep(3)
# 点击私信
csdn.clicksubmit("xpath", "/html/body/div[3]/div[1]/aside/div[1]/div[6]/div[1]/a")
time.sleep(1)
print("发送内容:")
# 切换到子标签页
current_windows = browser2.window_handles
browser2.switch_to_window(current_windows[1])
if(flag):
print(" "+ strs+" clock in Success!" + " by chuanshuai!")
csdn.inputvalue("id", "messageText", strs+" clock in Success!" + " by chuanshuai!")
else:
print(" "+ strs+" clock in Fail!" + " by chuanshuai!")
csdn.inputvalue("id", "messageText", strs+" clock in Fail!" + " by chuanshuai!")
csdn.Enter_strings("id", "messageText")
time.sleep(3)
print("-------------------------------")
# close只关闭了原本的页面
browser2.quit()
time.sleep(30)
上述程序有两处需要注意,第一处是option选项,通过这个参数让Firefox绕过window.navigator.webdriver控件检测,加上这个参数之后,程序调用浏览器,就不会弹出浏览器的界面 ,相对来说动静小一点,不会出现人不在电脑在动的情况吓到同事,不过在锁屏界面下没啥差别。
第二处则是切换到子标签页,csdn网页点击私信的时候,会重新弹出一个子标签页,此时xpath定位元素还是在第一个打开的标签页上查找,所有要有个切换的过程。
3.将新增的逻辑融入原本的程序
融入的逻辑很简单,基本上就是打卡程序之后,加上上面这些,在加个标志位。全体程序如下(cookie部分需要手动操作一次):
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# v1_0_0 by chuanshuai date: 2021.12.01 16:00
import time
from tim