Let's replace UWSC with Python (5) Let's make a Robot

Introduction

Part 5 of "Replacing UWSC with Python". This time we will actually make a robot. I couldn't post for a while due to various reasons.

Like the last time, I wrote it while checking it, so I think there are some mistakes. In that case, please make a Bishibashi edit request (sweat)

When I searched on UWSC, it seems that it was supplemented by the following site, so I will try to implement the desired function written in the forum.

CSWU-What to do Compatible system without UWSC https://wiki3.jp/CSWU

last time Replace UWSC with Python (4) Cheat Sheet [2] next time undecided </ font>

Let's make the missing function

We will create some of the features that UWSC does not have in this environment. The function to make is

―― 1. Image search (focus) highlight ―― 2. Element search (focus) highlight --3. GETID / CLKITEM compatibility function

In addition, the following sites were very helpful in creating the functions. If you have a function you want to create, you should refer to it.

Python Example https://www.programcreek.com/python/

1. Image Search (Focus) Highlights

When you search for images, you can easily understand where on the screen the match was made by drawing a rectangle on the screen. If you import win32gui and give (left, top, right, bottom), it will highlight the detected location. If you want to change the line type or color of the rectangle, you need to set it with win32ui.CreatePen, win32api.RGB, pyhandle, win32con.

func_dhlight.py


import win32gui

##Desktop highlights
def dhlight(x1, y1, x2, y2):
    hwnd=win32gui.WindowFromPoint((x1,y1))
    hdc=win32gui.GetDC(hwnd)
    rc=(x1, y1, x2, y2)
    win32gui.DrawFocusRect(hdc, rc)
    win32gui.ReleaseDC(hwnd,hdc)

if __name__ == '__main__':
    ##It feels like using it in combination with pyautogui's locateOnScreen.
    ##However, locateOnScreen is Box(left, top, width, height)Because it returns
    pos_x,pos_y,size_w,size_h  = pyautogui.locateOnScreen('target.png')
    x1 = pos_x
    y1 = pos_y
    x2 = pos_x + size_w
    y2 = pos_y + size_h
    dhlight(x1, y1, x2, y2)
    ##If you write, target.A dotted rectangle will be displayed where the png is found.

2. Element search (focus) highlight

When searching for an element on the browser, it will highlight which element was selected. Since this uses css insertion of selenium, it may not respond in the case of dynamic UI / UX or prohibiting rewriting of css (it is better to draw with win32gui by taking the coordinates of the element. maybe) I just plugged in css ("background: white; border: 1px solid blue;"), so I can change it to my liking.

func_hhlight.py


from selenium import webdriver
from selenium.common.exceptions import NoSuchElementException

##Highlights of Html Element
def hhlight(element):
    driver = element._parent
    def apply_style(s):
        driver.execute_script("arguments[0].setAttribute('style', arguments[1]);",element, s)
    original_style = element.get_attribute('style')
    apply_style("background: white; border: 1px solid blue;")
    time.sleep(.3)
    apply_style(original_style)


if __name__ == '__main__':
    driver = webdriver.Chrome()
    driver.implicitly_wait(10) 
    driver.set_page_load_timeout(5)
    driver.set_script_timeout(5)
    driver.get('https://www.google.com/')
    
    ##Like this, when you search for an element and pass the element to the created function, the specified CSS is applied,
    ##You will be able to see which element is selected
    search_box = driver.find_element_by_name("q")
    hhlight(search_box)

3. GETID / CLKITEM compatibility function

In UWSC, I used GETID to get the window ID and operated it, but it is difficult to do this in Python as it is, so I used a function to get the process ID from the window name (get_pid) and get the window handle from the process ID (get_hwnds). I decided to make it and deal with it.

func_getid.py


import os,sys,re,time,subprocess
import win32api, win32gui, win32con, win32process

def get_pid(title):
    hwnd = win32gui.FindWindow(None, title)
    threadid,pid = win32process.GetWindowThreadProcessId(hwnd)
    return pid

def get_hwnds(pid):
    def callback(hwnd, hwnds):
        if win32gui.IsWindowVisible(hwnd) and win32gui.IsWindowEnabled(hwnd):
            _, found_pid = win32process.GetWindowThreadProcessId(hwnd)
            if found_pid == pid:
                hwnds.append(hwnd)
        return True
    hwnds = []
    win32gui.EnumWindows(callback, hwnds)
    return hwnds 

def clkitem(win_title,itemid):
    #Search by window title
    hwnd = win32gui.FindWindow(0, win_title)

    #List items in the window
    inplay_children = []
    def is_win_ok(hwnd, *args):
        s = win32gui.GetWindowText(hwnd)
        inplay_children.append(hwnd)
    win32gui.EnumChildWindows(hwnd, is_win_ok, None)

    #Specify the item ID number and item/Get the handle of the button
    button_hwnd = inplay_children[itemid]

    #Activate the window
    win32gui.SetForegroundWindow(hwnd)
    #Click the specified button (press)->Send release)
    win32api.PostMessage(button_hwnd, win32con.WM_LBUTTONDOWN, 0, 0)
    win32api.PostMessage(button_hwnd, win32con.WM_LBUTTONUP, 0, 0)

#Get the process ID from the window ID
pid = get_pid(u"calculator")

#Click the first button on the calculator
clkitem(u"calculator",1)

#Get the handle from the process ID and operate[GETCTLHND]Equivalent to
for hwnd in get_hwnds(pid):
    if hwnd == 0:
        print(u"Window not found")
    else:
        #Size specification(resize)
        win32gui.MoveWindow(hwnd, 100, 100, 500, 500, True)
        #Maximize
        win32gui.ShowWindow(hwnd, win32con.SW_MAXIMIZE)
        time.sleep(1)
        #close
        win32gui.SendMessage(hwnd,win32con.WM_CLOSE,0,0)

You can now resize, move, and focus native apps on your screen. As far as the browser is concerned, it's easier to go with selenium.

Let's make a robot

<< Operation scenario >>

The part enclosed in [] is the module name to be used.

--1. Load ini (setting.ini) containing login information: [ConfigParser] --2 Open the browser, maximize it, and then go to the ini login_url: [Selenium] --3. Login using login information: [Selenium] --4. Move to the specified screen (post): [Selenium / win32gui] --5. Open the Excel file containing the entry information list [xlrd] --6.1 Line by line posted to input form [Selenium] ―― 7. When the last line of the Excel file is detected, close the screen and exit [Selenium]

Configuration file (setting.ini)

setting.ini


[Server]
login_id = user01
login_pw = password
login_url = https://127.0.0.1/wp/wp-login.php

[SitePage]
write_fourm =Post

[WriteFile]
excel_file = input_list.xlsx

input_list.xlsx


[Sheet1]
title,text,tag,format
Test 1,First post 1,Uncategorized,standard
Test 2,First post 2,Uncategorized,standard
Test 3,First post 3,Uncategorized,standard
Test 4,First post 4,Uncategorized,standard
Test 5,First post 5,Uncategorized,standard
Test 6,First post 6,Uncategorized,standard

Robot source

Actually, I will write the source according to the scenario. Actually, I should make more functions and make them easier to read, but I wrote them flat so that the scenario can be easily followed. Please note that it is written in UTF-8.

wordpress_auto_post.py


# -*- coding: utf-8 -*-

#Module loading
import os,sys,re,time,subprocess
import pyautogui
import win32gui
import configparser
import xlrd
from selenium import webdriver
from selenium.common.exceptions import TimeoutException
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.common.alert import Alert
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.select import Select

##Desktop highlights
def dhlight(x1, y1, x2, y2):
    hwnd=win32gui.WindowFromPoint((x1,y1))
    hdc=win32gui.GetDC(hwnd)
    rc=(x1, y1, x2, y2)
    win32gui.DrawFocusRect(hdc, rc)
    win32gui.ReleaseDC(hwnd,hdc)

##Highlights of Html Element
def hhlight(element):
    driver = element._parent
    def apply_style(s):
        driver.execute_script("arguments[0].setAttribute('style', arguments[1]);",element, s)
    original_style = element.get_attribute('style')
    apply_style("background: white; border: 1px solid blue;")
    time.sleep(.3)
    apply_style(original_style)

#Read configuration file
CONF_FILEPATH = 'setting.ini'
config = configparser.ConfigParser()
config.read( CONF_FILEPATH, 'UTF-8')

#In the conf file[]Specify the place surrounded by
config_server = config['Server']
config_page   = config['SitePage']
config_excel  = config['WriteFile']

#In conf[]Get the contents that contain variables and data under
uid = config_server['login_id']
upw = config_server['login_pw']
url = config_server['login_url']
search_button = config_page['write_fourm']
xlsxfile = config_excel['excel_file']

##Initialize Chrome
options = Options()

##Chrome path (usually no need to specify, when using portable version etc. or stable/When switching beta)
options.binary_location = 'C:\Program Files (x86)\Google\Chrome\Application\chrome.exe'
options.add_argument('--start-maximized')
options.add_argument('--disable-gpu')

##Create a Chrome WebDriver object.
driver = webdriver.Chrome(options=options,executable_path="C:\Python37\chromedriver.exe")

#Waiting time until the element is found, can be specified only immediately after driver generation
driver.implicitly_wait(10) 

#Specify to wait up to 5 seconds for the page to fully load, only immediately after driver generation
driver.set_page_load_timeout(5)

#Specify to wait up to 5 seconds until Javascript execution finishes
driver.set_script_timeout(5)

#URL move
driver.get(url)

#Login process
user_id_elm  = driver.find_element_by_id("user_login")
#Element highlight
hhlight(user_id_elm)
user_id_elm.send_keys(uid)

user_pw_elm  = driver.find_element_by_id("user_pass")
hhlight(post_fourm)
user_pw_elm.send_keys(upw)

login_submit = driver.find_element_by_id("wp-submit")
hhlight(post_fourm)
login_submit.submit()

time.sleep(5)

#Post
menu_post_elm = driver.find_element_by_xpath("/html/body/div[1]/div[1]/div[2]/ul/li[3]/a/div[3]")
hhlight(menu_post_elm)
menu_post_elm.click()

time.sleep(2)

#New addition
new_post_elm = driver.find_element_by_xpath("/html/body/div[1]/div[2]/div[2]/div[1]/div[3]/a")
hhlight(new_post_elm)
new_post_elm.click()

time.sleep(2)

#Open excel file
wb = xlrd.open_workbook(xlsxfile)

#Sheet designation
sheet = wb.sheet_by_name('sheet1')

#Last line detection
last_row = sheet.nrows

#Read into a two-dimensional array of all rows(If you don't have enough memory, you should read line by line)
readcells = [sheet.row_values(row) for row in range(sheet.nrows)]

time.sleep(5)

#Article title
card_title_elm = driver.find_element_by_xpath("//*[@id='post-title-0']")

#Article Text
card_body_elm = driver.find_element_by_xpath("/html/body/div[1]/div[2]/div[2]/div[1]/div[3]/div[1]/div/div/div/div[2]/div[3]/div/div[1]/div/div/div[2]/div[1]/div[3]/div/div/div/div/div/div/p")

#Exit driver
driver.close()

Move the robot

python ./wordpress_auto_post.py

It should move and be posted without any problems.

Finally

It really hurts to lose UWSC, and I hope there will be simpler automation tools. Next time, if I come up with something, I'll write a sequel.

Recommended Posts

Let's replace UWSC with Python (5) Let's make a Robot
Let's make a GUI with python.
Let's make a graph with python! !!
Let's make a shiritori game with Python
Let's make a voice slowly with Python
Let's make a web framework with Python! (1)
Let's make a Twitter Bot with Python!
Let's make a web framework with Python! (2)
Make a fortune with Python
[Let's play with Python] Make a household account book
Let's make a simple game with Python 3 and iPhone
[Super easy] Let's make a LINE BOT with Python.
Let's make a breakout with wxPython
Make a recommender system with python
Let's make a supercomputer with xCAT
Let's make a websocket client with Python. (Access token authentication)
Let's create a free group with Python
Let's make a simple language with PLY 1
Let's make a tic-tac-toe AI with Pylearn 2
Let's make a combination calculation in Python
Make a desktop app with Python with Electron
Let's make a web chat using WebSocket with AWS serverless (Python)!
Make a Twitter trend bot with heroku + Python
[Python] Make a game with Pyxel-Use an editor-
I want to make a game with Python
Try to make a "cryptanalysis" cipher with Python
[Python] Make a simple maze game with Pyxel
[Ev3dev] Let's make a remote control program by Python with RPyC protocol
Try to make a dihedral group with Python
Let's make a module for Python using SWIG
If you want to make a discord bot with python, let's use a framework
Make one repeating string with a Python regular expression.
Try to make a command standby tool with python
[Practice] Make a Watson app with Python! # 2 [Translation function]
[Practice] Make a Watson app with Python! # 1 [Language discrimination]
Make a simple Slackbot with interactive button in python
Make a breakpoint on the c layer with python
I want to work with a robot in python.
Let's make dependency management with pip a little easier
[For play] Let's make Yubaba a LINE Bot (Python)
Make a CSV formatting tool with Python Pandas PyInstaller
Let's make a Mac app with Tkinter and py2app
Let's make a spherical grid with Rhinoceros / Grasshopper / GHPython
What is God? Make a simple chatbot with python
[Piyopiyokai # 1] Let's play with Lambda: Creating a Python script
Let's make a Discord Bot.
Let's run Excel with Python
Let's make Othello with wxPython
Make a bookmarklet in Python
Let's write python with cinema4d.
Create a directory with python
Let's make a rock-paper-scissors game
Let's build git-cat with Python
Make a fire with kdeplot
[Practice] Make a Watson app with Python! # 3 [Natural language classification]
Associate Python Enum with a function and make it Callable
Let's create a script that registers with Ideone.com in Python.
Experiment to make a self-catering PDF for Kindle with Python
Let's create a PRML diagram with Python, Numpy and matplotlib.
Let's make a robot that solves the Rubik's Cube! 2 Algorithm
Let's make a spot sale service 4 (in Python mini Hack-a-thon)