selenium网页自动登录、打卡(二)


前言

前面做了一个自动打卡的小程序,基本可以实现上班签到,下班签退的任务,但还是有一些限制的,比如程序需要时时刻刻的运行在电脑上(可以在下班的时候将程序跑起来,但是电脑不能关机),这个问题对我来说其实还好,因为我下班本来就不关电脑。

另外一个比较重要的限制就是,很多时候由于网络等等莫名其妙的问题,很容易导致程序终止,总不能把每一行代码都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 time import strftime
import datetime
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver import ActionChains
import json
# import pyautogui
from selenium.webdriver.common.keys import Keys  

class LoginUrl(object):
	#初始化类的属性
	def __init__(self, driver, url, username, password):
		self.__driver = driver
		self.__url = url
		self.__username = username
		self.__password = password
	#打开网页的方法
	def openwebsite(self):
		self.__driver.maximize_window()
		self.__driver.get(self.__url)
	#输入网页账号
	def inputusername(self, find_element_method, element):
		if(find_element_method == "id"):		
			WebDriverWait(self.__driver, 10).until(EC.presence_of_element_located((By.ID, element)))#等待10s,每500ms查询一次,直到元素加载完毕或超过10s结束
			usrName = self.__driver.find_element_by_id(element)
		elif(find_element_method == "name"):
			WebDriverWait(self.__driver, 10).until(EC.presence_of_element_located((By.NAME, element)))
			usrName = self.__driver.find_element_by_name(element)
		elif(find_element_method == "xpath"):
			WebDriverWait(self.__driver, 10).until(EC.presence_of_element_located((By.XPATH, element)))
			usrName = self.__driver.find_element_by_xpath(element)
		else:
			print("find element error!")
		usrName.send_keys(self.__username)
	#输入网页密码
	def inputpassword(self, find_element_method, element):
		if(find_element_method == "id"):
			WebDriverWait(self.__driver, 10).until(EC.presence_of_element_located((By.ID, element)))
			passWrd = self.__driver.find_element_by_id(element)
		elif(find_element_method == "name"):
			WebDriverWait(self.__driver, 10).until(EC.presence_of_element_located((By.NAME, element)))
			passWrd = self.__driver.find_element_by_name(element)
		elif(find_element_method == "xpath"):
			WebDriverWait(self.__driver, 10).until(EC.presence_of_element_located((By.XPATH, element)))
			passWrd = self.__driver.find_element_by_xpath(element)
		else:
			print("find element error!")
		passWrd.send_keys(self.__password)
	#输入内容和字符
	def inputvalue(self, find_element_method, element, strings):
		if(find_element_method == "id"):
			WebDriverWait(self.__driver, 10).until(EC.presence_of_element_located((By.ID, element)))
			value = self.__driver.find_element_by_id(element)
		elif(find_element_method == "name"):
			WebDriverWait(self.__driver, 10).until(EC.presence_of_element_located((By.NAME, element)))
			value = self.__driver.find_element_by_name(element)
		elif(find_element_method == "xpath"):
			WebDriverWait(self.__driver, 10).until(EC.presence_of_element_located((By.XPATH, element)))
			value = self.__driver.find_element_by_xpath(element)
		else:
			print("find element error!")
		value.send_keys(strings)
	#点击登陆
	def clicksubmit(self, find_element_method, element):
		if(find_element_method == "id"):
			WebDriverWait(self.__driver, 5).until(EC.presence_of_element_located((By.ID, element)))
			self.__driver.find_element_by_id(element).click()
		elif(find_element_method == "name"):
			WebDriverWait(self.__driver, 5).until(EC.presence_of_element_located((By.NAME, element)))
			self.__driver.find_element_by_name(element).click()
		elif(find_element_method == "xpath"):
			WebDriverWait(self.__driver, 5).until(EC.presence_of_element_located((By.XPATH, element)))
			self.__driver.find_element_by_xpath(element).click()
		else:
			print( "find element error!")
	#点击打卡
	def test(self, find_element_method, element):
		ActionChains(self.__driver).move_to_element(self.__driver.find_element_by_xpath(element)).perform()
		self.__driver.find_element_by_xpath(element).click()

	# 输入字符串并enter出去
	def Enter_strings(self, find_element_method, element):
		ActionChains(self.__driver).move_to_element(self.__driver.find_element_by_id(element)).send_keys(Keys.ENTER).perform()

	# 获取CSDN的cookie
	def Get_cookie(self):
		# 等待手动登录csdn,用一个input等候
		input("input:")
		#获取cookie
		cookies = self.__driver.get_cookies()
		#cookie保存到cookies.txt文件
		f1 = open("cookies.txt","w")
		f1.write(json.dumps(cookies))
		f1.close
		print(type(cookies))	


def main():
	print("程序已经运行...")

	while(True):
		# 定义一个标志位,标志打卡是否成功
		flag = False

		# 计算几天的年月日,然后换算成周几,其中周六是5,周日是6,周一是0
		today = datetime.date(int(strftime('%Y',time.localtime(time.time()))),int(strftime('%m',time.localtime(time.time()))),int(strftime('%d',time.localtime(time.time()))))
		if(today.weekday()!=5 and today.weekday()!=6):
			if(
				# must
				strftime('%H:%M',time.localtime(time.time())) == "08:40" or 
				strftime('%H:%M',time.localtime(time.time())) == "18:40" or
				# need
				strftime('%H:%M',time.localtime(time.time())) == "19:50" or
				strftime('%H:%M',time.localtime(time.time())) == "21:00" or
				# test 
				strftime('%H:%M',time.localtime(time.time())) == "12:36" 
			  ):
				
				# Firefox绕过window.navigator.webdriver控件检测
				options1 = webdriver.FirefoxOptions()
				options1.add_argument("--headless") 
				options1.add_argument("--disable-gpu")
				profile = webdriver.FirefoxProfile()
				browser1 = webdriver.Firefox(options=options1,firefox_profile=profile)
				# browser1 = webdriver.Firefox()
				#登录
				xxx = LoginUrl(browser1, "your.html", u"your name", u"your password")
				xxx.openwebsite()
				# 输入账号
				xxx.inputusername("id", "loginid")
				# 输入密码
				xxx.inputpassword("id", "userpassword")
				# 点击登录
				xxx.clicksubmit("xpath", "//button[@id='submit']") 
				time.sleep(5)
				try:
					xxx.test("xpath","//button/span")
				except:
					print("-------------------------------")	
					print("已经打过卡了,只要重新更新时间即可...")
					try:
						xxx.test("xpath", "//a[@class='resign']")		# 有的时候浏览器会有特殊的页面,这句可能定位不到,从而报错
					except:
						print("遇到奇葩情况,打卡失败,等待下次重新打卡")
						flag = False
					else: 
						print("偷懒成功!")
						flag = True
				else:
					print("-------------------------------")
					print("偷懒成功!")
					flag = True
				
				# 定义一个字符串变量,作为发给csdn的数据
				strs = strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time()))
				print("当前时间:"+ strs)
				print("今天是周"+str(today.weekday()+1))
				browser1.quit()
				
				# 要先获取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)
				
			# 如果没到时间,休眠半分钟	
			else:
				time.sleep(30)
		else:
			# 更新weekday
			print("-------------------------------")
			today = datetime.date(int(strftime('%Y',time.localtime(time.time()))),int(strftime('%m',time.localtime(time.time()))),int(strftime('%d',time.localtime(time.time()))))
			print("当前时间:"+ strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time())))
			print("今天是周"+str(today.weekday()+1))
			print("-------------------------------")
			time.sleep(60*60*24)


if __name__ == "__main__":
	main()

在这里插入图片描述
在这里插入图片描述

  • 4
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值