Python automation script - involves pop-up, automatic login, screenshot, obtaining user permissions, packaging programs, etc

2020 summer XX bank Internship - an automated script

Many people learn python and don't know where to start.
After learning python and mastering the basic grammar, many people don't know where to find cases.
Many people who have done cases do not know how to learn more advanced knowledge.
So for these three types of people, I will provide you with a good learning platform, free video tutorials, e-books, and the source code of the course!
QQ group: 101677771

 

Internship background

I was lucky to have a one month internship in the financial technology center of a bank of China in 2020. My development work in the financial technology department is mainly to help develop an automatic program that can automatically log in to the web page and then take screenshots. Many functions and skills are involved in this project. I hereby write down the record. There may be mistakes in the description and code. Welcome to communicate with us.

Introduction to main functions

The flow of the whole program. After running, a dialog box will pop up to fill in the query keywords, which will be used for automatic web page search to reach the specified web page, then log in to the web page and automatically run to the last specified web page. The screenshot of the specified content will be saved to the folder and closed.

Obtain user rights and disable mouse and keyboard

When the script runs automatically, it is necessary to prevent users from entering and operating by mistake. It is necessary to prohibit the use of mouse and keyboard. Using a function ShellExecute, you can see the specific details ShellExecuteA function . A piece of code is posted here, which can be used directly.

from __future__ import print_function
import ctypes, sys

if windll.shell32.IsUserAnAdmin():
    //Running code
else:
    if sys.version_info[0] == 3:
    	ctypes.windll.shell32.ShellExecuteW(None, "runas", sys.executable, __file__, None, 1)
    	exit()//Because it will run even without permission, add exit to exit the program without permission.
    else:
    	//If Python 2 x
        ctypes.windll.shell32.ShellExecuteW(None, u"runas", unicode(sys.executable), unicode(__file__), None, 1)
        exit()

It is worth noting that if there is no administrator to run it, it actually runs twice. The first time I don't have permission, and the second time I get permission to run the code, so I added an exit function exit(). This is a point that needs to be improved. We will have a chance to see if it can be improved in the future.

reference resources: https://blog.csdn.net/qq_17550379/article/details/79006655

dialog box

The function of getting parameters and warning dialog box from dialog box is realized by using pyautogui library.

import pyautogui as pag

# Displays a simple message pop-up with text and OK button. The user clicks and returns the text of the button.
pag.alert(text='Internal contents of dialog box', title='Dialog Title ', button='Button')
//For example:
a = pag.alert(text='Do you want to start the program?', title='Request box', button='OK')
print(a) # The output result is the returned OK

# A simple message pop-up window with text, OK and Cancel buttons is displayed. After clicking, the user returns the text of the clicked button, and supports the list of custom numbers and text.
pag.confirm(text='Internal contents of dialog box', title='Dialog Title ', buttons=['OK', 'Cancel']) # The message pop-up window of OK and Cancel buttons, in which the number of buttons can be set with numbers
pag.confirm(text='', title='', buttons=range(10)) # Message pop-up window with 10 keys 0-9
//For example:
b = pag.confirm(text='', title='', buttons=range(10))
print(b) # The output result is the number of clicks

# The message that can be entered pops up with OK and Cancel buttons. The user clicks the OK button to return to the input text, and clicks the Cancel button to return to None. You can set a default input.
pag.prompt(text='Internal contents of dialog box', title='Dialog Title ', default='Default input')

# The style is the same as prompt(), which is used to enter the password, and the message is represented by *. With OK and Cancel buttons. The user clicks the OK button to return to the input text, and clicks the Cancel button to return to None.
pag.password(text='Internal contents of dialog box', title='Dialog Title ', default='', mask='*')

It mainly uses the dialog box and warning box for returning input. After obtaining the ID from the return box, it is used for subsequent search. When there is an error in the process of automatic operation, the warning box can remind the user.

reference resources: https://www.jb51.net/article/183926.htm

Automatically log in to web pages using Google chrome

It is a common method to use the driver of Google browser to automatically log in to the web page, which is also the method I used before. However, the logged in web page belongs to the internal network of the bank, and webdriver cannot be used to locate the web page elements. No matter which method is used, it is not possible, so I just use the driver to start a function of automatically opening the web page, and subsequent users log in, Automatic search and so on are simulated mouse and keyboard input using pyautogui.

chromedriver

Usually, you can log in automatically on the web page and use chromedriver. You can refer to Python to achieve automatic website login - fool tutorial . This method is also highly recommended, because simulating mouse click is really stupid. It is only suitable for some simple automatic scripts, but it can be said to be widely applicable.

Simulate mouse click and keyboard input

In fact, many modules have the function of keyboard input. What is needed is the click of the mouse. This is a stupid method, but it is simple, rough and practical. Of course, it is very inflexible. It mainly uses the library pyautogui

First, you can use the screenshot function of QQ or wechat to obtain the pixel coordinates of the specified points on the screen and record them as cur_x, cur_y

import pyautogui
pyautogui.click(x=cur_x, y=cur_y, button='left')
//x. y is the position to click, and the default is the current position of the mouse
//button is the key to be clicked and has three optional values: 'left', 'middle' and 'right'

Enter the user name and password by using the analog keyboard. It is worth noting that there are several points for attention:

  • Select and delete all before entering, that is, ctrl+a and del
  • Do not simulate the input of letters one by one. It is likely to be limited by the problem of input method. Use string copy and paste
import pyautogui as pag
   """Select all and delete"""
   pag.hotkey('ctrl','a')
   pag.press('delete')
  • 1
  • 2
  • 3
  • 4
import pyautogui as pag
import pyperclip
   """Enter the content. Using the shear board, you can ignore the problem of input method!"""
   char = 'User name or password'
   pyperclip.copy(char)
   pag.hotkey('ctrl','v')
  •  

I also use the locateOnScreen function of the library for pixel matching to judge whether the screenshot has reached the target area and the end position. If you are interested, you can click the link python captures and simulates mouse and keyboard operations , the reference is still the same as the first part.

reference resources: https://www.jb51.net/article/183926.htm

screenshot

There are too many methods for screenshots here, and many libraries provide methods. In fact, if it is a web page that can be crawled normally, it is recommended to export PDF instead of screenshots, so that the whole web page can be obtained. Screenshot normally, you can only get the content of the current screen. However, due to the intranet of the bank, the screenshot function of webdriver is used here.

driver.save_screenshot("Saved address")
  • 1

However, the above function can only intercept the pictures of the current page. We need to intercept more pictures, long pictures. There is ready-made code on the network, which can intercept the pictures separately and finally splice the long pictures. Because it's a long time ago, I forgot to refer to the link. Here's the code:

"""Intercept long graph"""
   window_height = driver.get_window_size()['height']  # Window height
   page_height = driver.execute_script('return document.documentElement.scrollHeight')  # Page height
   driver.save_screenshot('Partition map.png')
   if page_height > window_height:
       n = page_height // window_ Number of times height # needs to scroll
       base_mat = np.atleast_2d(Image.open('1.png'))  # Open screenshot and convert to 2D matrix

       for i in range(n):
           driver.execute_script(f'document.documentElement.scrollTop={window_height * (i + 1)};')
           time.sleep(.5)
           driver.save_screenshot(f'Partition map_{i}.png')  # Save Screenshot 
           mat = np.atleast_2d(Image.open(f'Partition map_{i}.png'))  # Open screenshot and convert to 2D matrix
           base_mat = np.append(base_mat, mat, axis=0)  # Two dimensional matrix of stitched pictures
       Image.fromarray(base_mat).save(char)

What is used now is to use whether the flag point appears on the screen to intercept all the contents of the specified area. The specific situation depends on the code.

All codes

"""Automatic script"""
"""Log in to the website and take a screenshot of the process"""
"""Basic implementation function version"""
""""In order to solve the problem that some computers run too slowly, add a text file to read and add the coefficient of waiting time time_k"""
import time
import os
from selenium import webdriver
import sys
from ctypes import *
from PIL import Image
import numpy as np
from win32 import win32api, win32gui, win32print
from win32.lib import win32con
from win32.win32api import GetSystemMetrics
import pyperclip

screen_w = GetSystemMetrics (0)
screen_h = GetSystemMetrics (1)
import pyautogui as pag
def main(screen_w , screen_h):
   #Read time parameters
   try:
       time_k = Read_txt()
   except:
       time_k = 1

   # Judge time parameters
   if time_k>5 or time_k<0.2:
       pag.alert(text='The time parameter setting is abnormal, please set it to 0.2~5 between', title='warning', button='OK')
       exit()

   #Permission acquisition
   Inner()

   #The user input box, for example, gz73002, can be used
   demand_id = pag.prompt(text='Please enter the process number(Please ensure that you use Google browser and the version is 83.0.4103 close)', title='Query business process', default='')
   if demand_id == None:
       exit()
   #Resolution judgment

   #Prompt box for screenshot naming
   title = pag.prompt(text='Please enter a title,Used for result naming (optional)', title='Title name input', default='')
   if title == None:
       title = " "

   resolution_judgment(screen_w,screen_h)

   # Environment configuration
   chromedriver = "C:\Program Files (x86)\Google\Chrome\Application"
   os.environ["webdriver.ie.driver"] = chromedriver

   driver = webdriver.Chrome()  # Select Chrome browser
   driver.get('website')  # Open website
   driver.maximize_window()  # Maximize Google browser


   time.sleep(2)
   try:
       #Disable mouse and keyboard
       windll.user32.BlockInput(True)

       time.sleep(1*time_k)

       #Enter user name and password
       username = ""  # user name
       #password = ""  # password
       password=Password()
       #Move the mouse to the user name
       Mouse_Click(1330,290)
       All_Del_Pag()
       Input_THING(username)


       #Move the mouse to the password
       Mouse_Click(1340,325)
       All_Del_Pag()
       Input_THING(password)

       Mouse_Click(1305,400)# Click login

       time.sleep(5*time_k)

       Mouse_Click(375,145)  # Click on personal homepage
       time.sleep(0.5*time_k)
       Mouse_Click(110,269)  # Click my task
       time.sleep(0.5*time_k)
       Mouse_Click(90,335)  # Click Done task
       time.sleep(4.5*time_k)

       #Input code
       Mouse_Click(600,351)
       All_Del_Pag()
       Input_THING(demand_id)
       Mouse_Click(918,353)  # Click OK
       time.sleep(2.5*time_k)

       Mouse_Click(1840,453)  # Click to view
       time.sleep(5*time_k)

       try:
           driver.switch_to.window(driver.window_handles[1])
       except:
           windll.user32.BlockInput(False)
           pag.alert(text='Wrong page! It may be due to the network\technological process ID non-existent\Input method problem, please check and try again', title='warning', button='OK')
           driver.close()
           exit()

       #Grab a feature to locate the bottom of the final screenshot
       try:
           pag.scroll(-90000)
           time.sleep(.5*time_k)
           flag_img = pag.screenshot(region=(206,817,25,25))
           time.sleep(.5*time_k)
           pag.scroll(90000)
       except:
           windll.user32.BlockInput(False)
           pag.alert(text='unknown error,Please contact the developer', title='warning', button='OK')
           driver.close()

       time.sleep(.5*time_k)
       Mouse_Click(231,299)  # Process view
       time.sleep(.5*time_k)

       """Start the screenshot and continue to turn down the screenshot until the logo features are identified"""
       try:
           t = True
           i = 1
           while t:
               Html_Png(driver,'\\%s%d.png'%(title,i))
               if pag.locateOnScreen(flag_img):
                   t = False
               pag.scroll(-1000)
               i=i+1
       except:
           windll.user32.BlockInput(False)
           pag.alert(text='unknown error', title='warning', button='OK')
           driver.close()

       time.sleep(.5)
       windll.user32.BlockInput(False)
       #Turn off the drive
       driver.close()

   except:
       windll.user32.BlockInput(False)
       driver.close()

def All_Del_Pag():
   #Select all and delete
   pag.hotkey('ctrl','a')
   pag.press('delete')

def Input_THING(char):
   """Enter the content. Using the shear board, you can ignore the problem of input method!"""
   pyperclip.copy(char)
   pag.hotkey('ctrl','v')

def Mouse_Click(x,y):
   #Move and click
   pag.moveTo(x,y)
   pag.click()

def Html_Png(driver,char):
   """screenshot"""
   Png_root = Local_Adr_G(char)
   try:
       driver.save_screenshot(Png_root)
   except:
       print('Screenshot error')

def Html_LongPng(driver,char):
   #Long screenshot function, CCB website can not be used, usually the website can
   window_height = driver.get_window_size()['height']  # Window height
   page_height = driver.execute_script('return document.documentElement.scrollHeight')  # Page height
   driver.save_screenshot('Partition map.png')
   if page_height > window_height:
       n = page_height // window_ Number of times height # needs to scroll
       base_mat = np.atleast_2d(Image.open('1.png'))  # Open screenshot and convert to 2D matrix

       for i in range(n):
           driver.execute_script(f'document.documentElement.scrollTop={window_height * (i + 1)};')
           time.sleep(.5)
           driver.save_screenshot(f'Partition map_{i}.png')  # Save Screenshot 
           mat = np.atleast_2d(Image.open(f'Partition map_{i}.png'))  # Open screenshot and convert to 2D matrix
           base_mat = np.append(base_mat, mat, axis=0)  # Two dimensional matrix of stitched pictures
       Image.fromarray(base_mat).save(char)

def Local_Adr(char):
   """Get current file path"""
   root = os.path.dirname(sys.argv[0])
   root = root + char
   return root

def Local_Adr_G(char):
   """Get the path of the process screenshot file under the current path"""
   root = os.path.dirname(sys.argv[0])+'\\Process screenshot'
   root = root + char
   return root
   
def Inner():
   #Get administrator privileges
   if windll.shell32.IsUserAnAdmin():
       return
   else:
       windll.shell32.ShellExecuteW(None, "runas", sys.executable, __file__, None, 0)
       sys.exit()

def get_real_resolution():
   """Get true resolution"""
   hDC = win32gui.GetDC(0)
   # Lateral resolution
   w = win32print.GetDeviceCaps(hDC, win32con.DESKTOPHORZRES)
   # Longitudinal resolution
   h = win32print.GetDeviceCaps(hDC, win32con.DESKTOPVERTRES)
   return w, h

def resolution_change(x,y):
   """Modify resolution"""
   dm = win32api.EnumDisplaySettings(None, 0)
   dm.PelsWidth = x
   dm.PelsHeight = y
   dm.BitsPerPel = 32
   dm.DisplayFixedOutput = 0
   win32api.ChangeDisplaySettings(dm, 0)

def resolution_judgment(w,h):
   """Resolution judgment"""
   real_resolution = get_real_resolution()
   screen_size = w,h
   screen_scale_rate = round(real_resolution[0] / screen_size[0], 2)
   if screen_size[0] == 1920:
       return
   else:
       if screen_scale_rate == 1:
           pag.alert(text='The scale is already 100%,Now the program tries to set the resolution automatically,\n If not, try setting 960 manually X540,And set the scale to 50%', title='explain', button='OK')
           resolution_change(1920,1080)
           exit()
       else:
           pag.alert(text='Wrong resolution!!\n Please click the icon in the lower left corner-set up-Display, set resolution and scale\n(1920X1080,100% Or 960 X540,50%)', title='warning', button='OK')
           exit()

def Read_txt():
   """Read file to get time parameter"""
   path = os.path.dirname(sys.argv[0])+'\\time.txt'
   with open(path,"r") as f:
       data = f.readline()
       return float(data)

def Read_Password():
   path = os.path.dirname(sys.argv[0])+'\\reg.txt'
   with open(path,"r") as f:
       data = f.readline()
       return data    

def Password():
   pa=Read_Password()
   ch=""
   for i in range(0,len(pa),5):
       asc=int(str(int(pa[i:i+5])*11)[-3:])
       ch=ch+chr(asc)
   return ch


if __name__ == '__main__':
   main(screen_w , screen_h)

Tags: Python Programming

Posted by hhheng on Fri, 20 May 2022 05:57:35 +0300