preface
The epidemic situation is repeated, and the school has started the daily health punch in, but there are always times when you forget to punch in. If you forget to punch in, you will be notified by the College..... So I thought of using Python to automatically punch in every day.
The health clock in our school can be on the web or mobile APP. Here, we will first implement the automatic clock in on the web, and then try to realize the automatic clock in on the mobile APP.
The clock out steps on the web side are as follows:
1. Log in to the health clock in page first
2. After entering, there is a health clock in "my application" at the left end. Hovering over it, the "enter" button will appear, and left click.
3. A window will pop up at the right end of the page to display the saved personal information. If there is no error, click "report" directly.
Operating principle
Python has a selenium library. This library was originally used for web automation testing. It can simulate people's various operations on the web page. We can use this library to realize automatic health clock out on the web page.
Operation steps
1, Construction of automation environment
1. Download and install Firefox browser
2. Install the Firefox driver geckodriver
Download the geckodriver compressed package. If the following web address cannot be opened, you can directly search the browser for the keyword geckodriver to download
$ wget https://github.com/mozilla/geckodriver/releases/download/v0.29.1/geckodriver-v0.29.1-linux64.tar.gz
decompression
$ tar -xvzf geckodriver*
Add execution permission
$ chmod +x geckodriver
Move the extracted executable file to the / usr/local/bin / directory
$ sudo mv geckodriver /usr/local/bin/
3. Add the geckodriver executable to the global PATH
Edit the / etc/profile file
$ chmod 777 /etc/profile $ vim /etc/profile
Add export PATH=$PATH:/usr/local/bin/geckodriver on the last line
Save, exit and restart the system to make it effective.
4. Install the selenium Library of Python
$ pip3 install selenium
2, Edit automatic clock out script
# Sets the size of the window in headless mode (no web pages are displayed) import os os.environ['MOZ_HEADLESS_WIDTH'] = '1920' os.environ['MOZ_HEADLESS_HEIGHT'] = '1080' import time from selenium import webdriver from selenium.webdriver.firefox.options import Options from selenium.webdriver.common.keys import Keys from selenium.webdriver.common.action_chains import ActionChains # Set the browser to headless mode and start with window maximization options=Options() options.add_argument('--headless') options.add_argument('--window-size=1920,1080') options.add_argument("--start-maximized") # Instantiate Firefox browser driver= webdriver.Firefox(executable_path = '/usr/local/bin/geckodriver',options=options) # Open the health clock in website url = r"http://XXXX/XXXXX" driver.get(url) # Maximize browser form driver.maximize_window() # Fill in the user name and password to enter driver.find_element_by_id("username").send_keys("XXXXXX") #Fill in user name here driver.find_element_by_id("password").send_keys("xxxxxxxxxxx") #Enter password here driver.find_element_by_id("password").send_keys(Keys.RETURN) time.sleep(1) # Click with absolute coordinates to enter the health report ActionChains(driver).move_by_offset(214,390).click().perform() ActionChains(driver).move_by_offset(-214,-390).perform() # Confirm the default filling information time.sleep(1) ActionChains(driver).move_by_offset(1723,683).click().perform()
3, Using crontab to set Python scripts to execute automatically and regularly
Edit crontab profile
$ crontab -e
For the first time, you may need to select the default editor
Add on the last line
# m h dom mon dow command 30 9 * * * python3 /home/XXX/XXX/XXXX.py
Set 9:30 a.m. every day to automatically execute XXXX under / home/XXX/XXX / path Py script
Refresh crontab configuration information to make it effective
$ sudo service cron restart
be careful:
To turn off the automatic screen lock / sleep of the system, because the user will log out after the automatic screen lock / sleep, and the script cannot be executed automatically.
Problems encountered and Solutions
1. Unable to locate the "enter" that can only appear when the "health clock in" mouse hovers
The initial script is as follows. Because I haven't learned web crawler, it's particularly difficult to locate web elements. After entering the web page, I can't find it on the Internet_ element_ by_ id,class_name,tag_name,link_text, xpath and other methods, locate the "enter" button that can only appear when the mouse hovers over the "health punch in".
from selenium import webdriver from selenium.webdriver.common.keys import Keys # Instantiate Firefox browser driver= webdriver.Firefox() # Open the health clock in website url = r"http://XXXX/XXXXX" driver.get(url) # Maximize browser form driver.maximize_window() # Fill in the user name and password to enter driver.find_element_by_id("username").send_keys("XXXXXX") #Fill in user name here driver.find_element_by_id("password").send_keys("xxxxxxxxxxx") #Enter password here driver.find_element_by_id("password").send_keys(Keys.RETURN)
Finally, we have no choice but to directly use the universal screen coordinate method to operate the web page element according to the absolute position of the screen, but this brings hidden dangers: reduce the portability of the script. If the screen size changes, it will directly affect the absolute coordinates of the web page element, so the operation on the absolute coordinates will make mistakes.
However, I have not found a good solution, so I can only use the coordinate method for the time being. About how to determine the coordinate value, you can use the system's own screenshot tool, and the coordinate value will be prompted during the screenshot.
Here I post the web page code. If there is a great God who knows how to locate this part of the content, I can give you some advice. Thank you very much
Use of coordinate method
It should also be noted that the zero point of the web page operation coordinate is located in the upper left corner below the title bar and label bar, that is, the upper left corner of the real content of the web page. Moreover, if the coordinate operation is used twice in succession, the zero point of the second coordinate operation is the end position of the first coordinate operation. So we're at the foot
In this, the "zero return" operation is required after using the coordinate operation once, and then use the second time.
#First operation ActionChains(driver).move_by_offset(214,390).click().perform() #Return to zero ActionChains(driver).move_by_offset(-214,-390).perform() #Second operation ActionChains(driver).move_by_offset(1723,683).click().perform()
2. Error prompt: selenium common. exceptions. WebDriverException: Message: ‘geckodriver’ executable needs to be in PATH.
resolvent:
You need to add geckodriver to the PATH (the method described above) and change the code at the same time
driver= webdriver.Firefox() #Change to driver= webdriver.Firefox(executable_path = '/usr/local/bin/geckodriver')
3. Error prompt: selenium common. exceptions. WebDriverException: Message: Process unexpectedly closed with status 1. Also at geckodriver Log prompt: Error: no DISPLAY environment variable specified
Solution: the browser opens in headless mode
from selenium import webdriver from selenium.webdriver.firefox.options import Options options=Options() options.add_argument('--headless') driver= webdriver.Firefox(executable_path = '/usr/local/bin/geckodriver',options=options) #Using Firefox
4. Error prompt: selenium common. exceptions. MoveTargetOutOfBoundsException: Message: (1723, 541) is out of bounds of viewport width (1366) and height (683)
Reason: Although the web page opened in headless mode is not displayed, a "window" will still be opened. The default size of the window on my computer is (1366683). If it is not a maximized window, some web page elements are not fully displayed, so the error prompts that the web page operation exceeds the boundary.
Solution: we need to change the size of the default window in headless mode to full screen size, and add the following statement at the beginning of the program
import os os.environ['MOZ_HEADLESS_WIDTH'] = '1920' os.environ['MOZ_HEADLESS_HEIGHT'] = '1080'