I tried to easily create a fully automatic attendance system with Selenium + Python

I think that there are many people who work by telework or remote work due to the turmoil of the new virus. Telework was started at the company I work for with the declaration of emergency, but since there were troublesome rules, I tried to automate it easily with Selenium and Python.

By the way, as soon as we lifted the state of emergency, we went to work and sometimes worked from home.

At your own risk

Please use ** self-responsibility ** to introduce in this article. There is also such an approach, I hope you can see it with a sense of temperature. I can imagine if I'm using it.

This time, we are only talking about the in-house original system installed on the in-house server. Of course, there are many services for which automation is prohibited, so please make sure that you do not violate the terms of use when using it with an external service, and then do so at your own risk.

Now that the introduction is over, let's automate it immediately.

Telework environment and rules

I think there are various telework rules in the world, but this time I will talk on the premise of the following environment and rules.

environment

--During telework, connect from your home PC to your company's own PC using remote desktop via VPN --The own PC does not shut down during the telework period and is in operation for 24 hours. --Various in-house systems can be connected only from the in-house network --The in-house system can be used with a browser, and APIs cannot be used at all (there is a theory that APIs are not implemented in the first place).

Rules for starting telework work

--Write today's scheduled working hours on the telework channel of the company chat --Send the same content as chat to managers and bosses by in-house email --Register the start time in the in-house work management system

In other words, you need to connect to the VPN shortly before the start time (9:00 AM), send similar content by chat and email every day, and register it in the company's work management system. With this, I have to get up before the start of work, start the PC, connect the VPN, and so on, so I don't feel that I have more time to spare in the morning even though I have run out of commuting time.

~~ Above all, it is troublesome to get up at the start of work because of that. ~~

Try automating with Selenium and Python

Fortunately, all in-house systems can be accessed from a browser, so let's try to automate Selenium, which is familiar with browser automation, by running it in Python.

Chat automation

As for chat, the channel to write and the wording are fixed, so it can be easily automated by doing the same as human operation. Let's take the chat tool "Mattermost" for on-premise as an example.

driver = webdriver.Chrome()
#Log in to Mattermost
driver.get("http://192.168.0.100/system-dev/channels/remotework") #Telework channel
time.sleep(5)
driver.find_element_by_name("loginId").send_keys("[email protected]") #username(mail address)
driver.find_element_by_name("password").send_keys("Password") #password
time.sleep(1)
driver.find_element_by_id("loginButton").click() #Press login button
time.sleep(5)
chatbox = driver.find_element_by_id("post_textbox") #Get chat input field
#Contents to write from here
chatbox.send_keys("Good morning. It is a company slave.")
chatbox.send_keys(Keys.SHIFT, Keys.ENTER)
chatbox.send_keys("[Today's working hours]")
chatbox.send_keys(Keys.SHIFT, Keys.ENTER)
chatbox.send_keys("Scheduled working hours: 09:00 - 18:00")
chatbox.send_keys(Keys.SHIFT, Keys.ENTER)
chatbox.send_keys("【Lunch break(1.0h)】")
chatbox.send_keys(Keys.SHIFT, Keys.ENTER)
chatbox.send_keys("Scheduled break time: 12:00 - 13:00")
chatbox.send_keys(Keys.SHIFT, Keys.ENTER)
chatbox.send_keys("[Other]")
chatbox.send_keys(Keys.SHIFT, Keys.ENTER)
chatbox.send_keys("None")
#So far
chatbox.submit()
time.sleep(5)
driver.quit()

Start the browser like this → Access the URL of the specified channel → Login → Automate chat writing. time.sleep is a process that just waits at the part where the process seems to run after loading the page. It probably works without it, but it's insurance.

When you start the browser with Selenium, it basically starts in a blank state like a secret window where the ID and password are not remembered, so you need to enter the login process, but other than that, you need to manually It is the same as the work to be done.

I enter the content of the chat with a line break, but in my environment I can do it with Shift + Enter. I think there is a tool that breaks a line with Ctrl + Enter, so change that as appropriate.

After that, when testing, please test by creating a channel for only one person. If you make a mistake in the bumping production, you will probably be suspicious.

Email automation

The mail system can be accessed from a browser, and mail can be received and sent from the browser, so I tried to automate it. The mail system that can be used with the browser is operated by another company, but it should be okay because the terms of use did not say that automation is useless.

Start the browser → Access the URL of the mail system → Login → Create a new mail → Enter the contents of the mail → Send it. This is no different from honest chat.

The code is not much different from the previous one, but since there was a rule to put the date in the subject in the email, I will write the processing around that as a sample.

"[Company slave project] [Start of employment]" + datetime.date.today().strftime("%Y%m%d") + "Progress report (Taro company slave)"

The subject had to be something like "[project name] [start of employment] 2020/10/01 progress report (name)", so I got the run-time date and automated it.

After that, the mail composition screen is displayed in a separate window, so I added a process to change the focus window (operation target window).

driver.switch_to.window(driver.window_handles[1])

It seems that windows are managed by a string called window handles, but this time it pops up only once, so specify driver.window_handles [1] and specify the first window opened driver.window_handles [0] It is specified as a window opened next to.

It seems that you can use driver.window_handles [-1] to specify the last window opened.

The work management system is automated in the same way

It's almost the same when you go this far. Just hit the URL → login → operate. When operating, you only need to specify the element with ʻidorclass name`, so there is no choice but to pick it up with the developer tools.

Schedule execution

After the operation automation in Selenium is finished, the next step is to implement scheduled execution.

Specifically, these automation operations need to be performed "as if you were at work."

In this example, it will be 9:00 AM, but if you start at 9:00 AM, do you have a seat at 9:00 AM?

I think I'll be seated a little before 9:00 AM. On the other hand, there are times when you are delayed for a few minutes, such as a slight delay in the train or a missed train, right? Even if you take the same train every day, the work hours may vary by a few minutes depending on the weather and temperature.

In other words, it's unnatural if chats and emails aren't sent at some random time just before 9:00 AM.

So, this time, we will implement the process to execute the schedule at a random time from 8:50 to 9:00.

chattime = ""

def timeset():
    chattime = random.randint(50, 60)
    if chattime < 10:
        #If it is less than 10 minutes, fill it with zeros.
        chattime = "0" + str(chattime)
    if chattime == 60:
        #9 for 60 minutes:Interpret as 00
        schedule.every().day.at("09:00").do(job)
        print("09:00")
    else:
        schedule.every().day.at("08:" + str(chattime)).do(job)
        print("08:" + str(chattime))


schedule.every().day.at("08:00").do(timeset)

while True:
    schedule.run_pending()
    time.sleep(60)

Like this, I decided the time to contact work every day at 8:00 AM with a random function, and when that time came, I decided to contact work.

It's pretty rough in terms of processing, but after defining all the functions, it loops infinitely at the last while True, executes all the schedules → repeats sleep for 1 minute.

At the time of execution, register a schedule to execute timeset at 8:00 AM withschedule.every (). day.at ("08: 00") .do (timeset), and in timeset Random numbers from 50 to 60 are generated and an additional schedule is registered according to the numbers.

In order to correspond to other than 50-60, if it is 10 minutes or less, the beginning is filled with 0, and when 60 comes out, it is interpreted as 9:00. However, the requirements have been met, so it is OK.

Whole code

#!python3.8
import time
import datetime
import schedule
import random
import sys
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait


def job():
driver = webdriver.Chrome()
    #Log in to Mattermost
    driver.get("http://192.168.0.100/system-dev/channels/remotework") #Telework channel
    time.sleep(5)
    driver.find_element_by_name("loginId").send_keys("[email protected]") #username(mail address)
    driver.find_element_by_name("password").send_keys("Password") #password
    time.sleep(1)
    driver.find_element_by_id("loginButton").click() #Press login button
    time.sleep(5)
    chatbox = driver.find_element_by_id("post_textbox") #Get chat input field
    #Contents to write from here
    chatbox.send_keys("Good morning. It is a company slave.")
    chatbox.send_keys(Keys.SHIFT, Keys.ENTER)
    chatbox.send_keys("[Today's working hours]")
    chatbox.send_keys(Keys.SHIFT, Keys.ENTER)
    chatbox.send_keys("Scheduled working hours: 09:00 - 18:00")
    chatbox.send_keys(Keys.SHIFT, Keys.ENTER)
    chatbox.send_keys("【Lunch break(1.0h)】")
    chatbox.send_keys(Keys.SHIFT, Keys.ENTER)
    chatbox.send_keys("Scheduled break time: 12:00 - 13:00")
    chatbox.send_keys(Keys.SHIFT, Keys.ENTER)
    chatbox.send_keys("[Other]")
    chatbox.send_keys(Keys.SHIFT, Keys.ENTER)
    chatbox.send_keys("None")
    #So far
    chatbox.submit()
    time.sleep(5)
    driver.quit()

    #send e-mail
    driver = webdriver.Chrome()
    driver.get("https://webmail.example.com/login")
    time.sleep(5)
    #Login ID
    driver.find_element_by_name("login_id").send_keys("[email protected]")
    #password
    driver.find_element_by_name("pass").send_keys("password")
    time.sleep(1)
    driver.find_element_by_xpath("//input[@value='Login']").click()
    time.sleep(5)
    #Email composition screen
    driver.find_element_by_id("smail").click()
    time.sleep(5)
    driver.switch_to.window(driver.window_handles[1])
    #Compose an email
    driver.find_element_by_id("to").send_keys("[email protected]")
    driver.find_element_by_id("subject").send_keys(
        "[Company slave project] [Start of employment]" + datetime.date.today().strftime("%Y%m%d") + "Progress report (Taro company slave)"
    )
    driver.find_element_by_id("content").send_keys(
        "Dear Sir\n Thank you for your hard work. It is a company slave.\n I would like to report on today's work schedule.\n\n [Today's working hours]\n Scheduled working hours: 09:00 - 18:00\n [Lunch break(1.0h)】\n Scheduled break time: 12:00 - 13:00\n [Other]\n None\n------------------------------------------------------------\n Company Slave Development Department Co., Ltd.\n Company slave Taro/ Taro Shachiku \n  mail: [email protected]\n------------------------------------------------------------"
    )
    #send e-mail
    driver.find_element_by_id("send_mail").click()
    time.sleep(10)
    driver.quit()

    #Attendance system input
    driver = webdriver.Chrome()
    driver.get("http://192.168.0.200/kinmu/login")
    time.sleep(5)
    driver.find_element_by_id("userId").send_keys("114514")
    driver.find_element_by_id("password").send_keys("password")
    driver.find_element_by_class_name("login_button").click()
    time.sleep(10)
    yesterday = datetime.date.today() - datetime.timedelta(days=1)
    driver.find_element_by_id(
        "dailyList["
        + datetime.date.strftime(yesterday, "%d")
        + "].orderList[0].resultEnterTime"
    ).send_keys("0900")
    driver.find_element_by_name("update").click()

    time.sleep(10)
    alert = driver.switch_to.alert
    alert.accept()

    time.sleep(10)
    driver.quit()

    sys.exit()


chattime = ""


def timeset():
    chattime = random.randint(50, 60)
    if chattime < 10:
        chattime = "0" + str(chattime)
    if chattime == 60:
        schedule.every().day.at("09:00").do(job)
        print("09:00")
    else:
        schedule.every().day.at("08:" + str(chattime)).do(job)
        print("08:" + str(chattime))


schedule.every().day.at("08:00").do(timeset)

while True:
    schedule.run_pending()
    time.sleep(60)

Summary

It seems that all routine work that can be done from the browser can be automated like this.

With this, even if you get up after 9 o'clock and take a bath and then connect to the VPN, it seems that you are working hard before 9 o'clock.

If you do it before leaving work the day before, even if you get up a little late the next day, it looks like you are going to work, so it's safe!

However, there is a possibility that chats may have been skipped before starting work properly, so it is most important to keep the dosage and keep it moderate.

I hope this will reduce the amount of shit work done because "it doesn't have a deep meaning, but it's a rule".

Recommended Posts

I tried to easily create a fully automatic attendance system with Selenium + Python
I tried to create a list of prime numbers with python
I tried to make a periodical process with Selenium and Python
I tried to create a program to convert hexadecimal numbers to decimal numbers with python
[Outlook] I tried to automatically create a daily report email with Python
I tried to draw a route map with Python
I tried to automatically generate a password with Python3
I tried to make a periodical process with CentOS7, Selenium, Python and Chrome
I tried to create a class that can easily serialize Json in Python
When I tried to create a virtual environment with Python, it didn't work
I tried to automatically create a report with Markov chain
[Python] I tried to automatically create a daily report of YWT with Outlook mail
I tried scraping food recall information with Python to create a pandas data frame
I tried to create a linebot (implementation)
[5th] I tried to make a certain authenticator-like tool with python
I made a library to easily read config files with Python
I tried to create a linebot (preparation)
[2nd] I tried to make a certain authenticator-like tool with python
A memorandum when I tried to get it automatically with selenium
[3rd] I tried to make a certain authenticator-like tool with python
[Python] A memo that I tried to get started with asyncio
I tried a functional language with Python
I tried to make a 2channel post notification application with Python
I tried to create Bulls and Cows with a shell program
I tried to make a todo application using bottle with python
[4th] I tried to make a certain authenticator-like tool with python
I tried to easily detect facial landmarks with python and dlib
[1st] I tried to make a certain authenticator-like tool with python
I tried to easily create a high-precision 3D image with one photo [2]. (Try processing depth with numpy)
Python: I tried to make a flat / flat_map just right with a generator
I tried to communicate with a remote server by Socket communication with Python.
I made a tool to automatically browse multiple sites with Selenium (Python)
I tried to create a plug-in with HULFT IoT Edge Streaming [Development] (2/3)
I tried to make a traffic light-like with Raspberry Pi 4 (Python edition)
I tried to create a plug-in with HULFT IoT Edge Streaming [Execution] (3/3)
I tried to discriminate a 6-digit number with a number discrimination application made with python
I tried to create a plug-in with HULFT IoT Edge Streaming [Setup] (1/3)
I tried to build a Mac Python development environment with pythonz + direnv
I tried to create a sample to access Salesforce using Python and Bottle
I want to easily create a Noise Model
You can easily create a GUI with Python
I tried to get CloudWatch data with Python
I tried to output LLVM IR with Python
Steps to create a Twitter bot with python
I tried to automate sushi making with python
Create a Python console application easily with Click
I want to write to a file with Python
I tried to make a simple mail sending application with tkinter of Python
[Patent analysis] I tried to make a patent map with Python without spending money
I tried to explain what a Python generator is for as easily as possible.
[ES Lab] I tried to develop a WEB application with Python and Flask ②
I tried to easily visualize the tweets of JAWS DAYS 2017 with Python + ELK
I tried to create a button for Slack with Raspberry Pi + Tact Switch
I tried to create an environment to check regularly using Selenium with AWS Fargate
I tried to create a model with the sample of Amazon SageMaker Autopilot
I want to easily implement a timeout in python
I tried to implement Minesweeper on terminal with python
I tried to get started with blender python script_Part 01
I tried to touch the CSV file with Python
I tried to solve the soma cube with python
Why not create a stylish table easily with Python?