The shy of bush
6 min readJan 13, 2022

--

Reporting Body Temperature to the Temperature System of the school automatically

Motivation

Since the Covid-19 Pandemic happened, my school required every student to report body temperature to the temperature report system in the period between AM six a.m. to eight a.m. every single day to avoid spreading the disease/virus. I think this policy really unnecessary and useless. Because no one would report the real body temperature, instead, it brings trouble for every student, because everyone is lazy, including me. The important is that if you forget to report the temperature, then you would get an admonition.

I absolutely do not accept this troublesome requirement. So I determine to write a web crawler to automatically report body temperatures.

In the beginning, it was very successful; I use the web crawler to report temperature. I used it to report my temperature, as usual, so I found it didn’t successfully report the temperature, it could only report manually I saw the interface, which made me really dumbfounded when I opened the website.

To be honest, I am a little surprised and dumbfounded simultaneously when I saw this interface, therefore I began to think of a solution.

Start making

Ideas 1

developmental language: python

using extension package:

import requests  
from bs4 import BeautifulSoup, element
from selenium import webdriver
import selenium import time

at first, I use requests to crawl the website down, then put it in the BeautifulSoup to dissect.

url='https://webap1.kshs.kh.edu.tw/kshsSSO/publicWebAP/bodyTemp/index.aspx' 
r=requests.get(url)
soup=BeautifulSoup(r.text,'lxml')

Now I crawled the website down, then my mission is to let the computer check the correct option.

The approach that would occur problem in getting the verification number.

the website after BeautifulSoup dissect, then use the approach find$=(id=’ContentPlaceHolder1_lb’) to find the area of verification number out from HTML, and save the tag_verification_num.string (verification number) into variable tag_verification_num .but now the problem is coming, when I print variable tag_verification_num out, the value is null.

Solution

After dissecting the website through beautifulsoup , use the approach find$=(id=’ContentPlaceHolder1_lb’) to find the area of display the verification number, and after saving ag_verification_num.string(verification number) into the variable tag_verification_num, transit type to string, then I find this span label trans type to string that 65th char is the verification number.

Then I save it into variables, for later use.

tag_verification_num=soup.find(id='ContentPlaceHolder1_lbN') num_verification=str(tag_verification_num) num_verification=num_verification[65]

Now I acquired the verification number, next I need to get the numbers of each verification option.

the HTML structure of the verification option used the span label to wrap the input option and label of the number of display the option.

So I through approach find.(id=’ContentPlaceHolder1_RadioButtonList1') to find input label and its father span, then save it into variable tag_verification, and then through approach tag_verification.find_all(‘input’) to find all the input labels in the span.

tag_verification=soup.find(id='ContentPlaceHolder1_RadioButtonList1') 
tag_verification_input=tag_verification.find_all('input')

The approach of incorrect to get the option value

After being through approach tag_verification.find_all(‘input’) to get all input labels in the span label, then use the loop for i in tag_verification_input: to access the value of each input label, but I have a problem likely above this moment, that displays null when I print variable i.

Solution

here can also use the same solution as above, trans input label type to string, and find value is which first few char among the string, so that I can get numbers of verification option.

tag_verification=soup.find(id='ContentPlaceHolder1_RadioButtonList1') tag_verification_input=tag_verification.find_all('input') for i in tag_verification_input:     
num_input=str(i)
num_input[121]//驗證選項的數字

Because the input label in variable tag_verification_input is repaced by variable i in the for loop, so variable i will replace the verification option below.

Now I acquired the verification number and also get the number of each option, next step is that I want to make programming to determine which number of options are equal to the verification number.

I added the conditional expressions into the loop for i in tag_verification_input: , for determining whether 121st char of the char variable i trans type to string are equal variable num_verification .

for i in tag_verification_input:     
num_input=str(i)
if num_verification==num_input[121]:
//填報體溫

I already know the input label which corresponds to the verification number, now I should know the attribute of this input label so that I can use the approach find_element_by_name() to control webdriver to check correct option. if use the approach of most intuition num_input=i.name , that the value of variable num_input is null same with above. So also have to trans variable i type to string, and then num_input[57:99] would save chars that range in 59th to 99th, which is the name of variable i .

After I acquired the name of the input label, then I can control webdriver to check the correct option.

import requests 
from bs4 import BeautifulSoup, element
from requests.models import Response
from selenium import webdriver
import selenium
import time

url='https://webap1.kshs.kh.edu.tw/kshsSSO/publicWebAP/bodyTemp/index.aspx'
r=requests.get(url)
soup=BeautifulSoup(r.text,'lxml')

driver=webdriver.Chrome("./chromedriver")
driver.get(url)

tag_verification_num=soup.find(id='ContentPlaceHolder1_lbN')
num_verification=str(tag_verification_num)
num_verification=num_verification[65]
def enter_step1():
tag_input = driver.find_element_by_name("ctl00$ContentPlaceHolder1$txtId")
tag_input.send_keys('(身分證字號)')
driver.find_element_by_name("ctl00$ContentPlaceHolder1$btnId").click()
def enter_step2():
driver.find_element_by_name('ctl00$ContentPlaceHolder1$rbType').click()
driver.find_elenent_by_xpath('//*[@id="ContentPlaceHolder1_ddl1"]/option[3]').click()
driver.find_element_by_xpath('//*[@id="ContentPlaceHolder1_ddl2"]/option[3]').click()
driver.find_element_by_xpath('//*[@id="ContentPlaceHolder1_ddl3"]/option[2]').click()
driver.find_element_by_name('ctl00$ContentPlaceHolder1$btnId0').click()
tag_verification=soup.find(id='ContentPlaceHolder1_RadioButtonList1')
tag_verification_input=tag_verification.find_all('input')


for i in tag_verification_input:
num_input=str(i)
print('迴圈外',num_input[121])
if num_verification==num_input[121]:
print('要驗證的數字',num_verification)
print('要輸入的數字',num_input[121])
print('secess\n')
print(i)
print(type(i),'\n')
print(num_input[57:99])
print(type(num_input[57:99]))
print('選取的數字:',num_input[121])
driver.find_element_by_name(num_input[57:99]).click()
enter_step1()
enter_step2()
else:
print('fail')
time.sleep(3)
driver.quit()

Improve

Motive 2.0

2021/4/21 school website manager update the body temperature report system again.

The verification function change to answer an unpredictable question, this update makes me surprise again. by the way, I suggest that next time update the verification function to solve calculus.

Idea 2.0

whimsical

My initial idea is that the school website manager would put the question of basic knowledge as everyone knows, so I planning to use function requests and beautifulsoup to grab the question down, and then through Wikipedia to search the correct answer, finally , determine whether both answers from Wikipedia and verification system is same.

problem: After altering the verification approach, I find discover that requests and beautifulsoup are useless to dissect any attribute of the label.

Solution: Lacking ability, no solution.

exhaustive solution

subsequently, I invent an approach that is able to ignore any value of label and verification questions. That is all the id attribute of input label that front section in the string is ContentPlaceHolder1_RadioButtonList1_ , and the last number is option bumber, for example:

first option:ContentPlaceHolder1_RadioButtonList1_0
seconde option:ContentPlaceHolder1_RadioButtonList1_1
third option:ContentPlaceHolder1_RadioButtonList1_2

Then I can follow the regulation to try each option, soI can solve this problem.

Function

In order to be convenient, I would set the function to represent any operation except verification.

  1. enter_step1()

function: input the identity id and click the submit button.

def enter_step1():
print('step1')
driver.find_element_by_id('ContentPlaceHolder1_txtId').
send_keys('(身分證字號)')
driver.find_element_by_id('ContentPlaceHolder1_btnId').click(

2. enter_step2()

function: fill body temperature state and attendance status

def enter_step2():
print('step2')
driver.find_element_by_id('ContentPlaceHolder1_rbType_1').click()
driver.find_element_by_xpath('//*[@id="ContentPlaceHolder1_ddl1"]/option[3]').click()
driver.find_element_by_xpath('//*[@id="ContentPlaceHolder1_ddl2"]/option[4]').click()
driver.find_element_by_xpath('//*[@id="ContentPlaceHolder1_ddl3"]/option[2]').click()

3. submit()

function: click the button of fill completed.

def sunmit():    
print('submit')
driver.find_element_by_id('ContentPlaceHolder1_btnId0').click()

verification

First, remove all the last number that presents option number, among the id attribute string, and save this string into variable id .

id='ContentPlaceHolder1_RadioButtonList1_'

Because the option amount will change every day, but according to my observation, that is up to four. So I use the loop for i in range(3) , and declared a variable is equal to name+str(i) , that able to through for loop get each attribution of variable i of input label and then put that variable into the function find_element_by_id() , try every lap. Because if fail to verification, the progress continues to report body temperature, it will get an error, So I must set the except handling in the for loop, if the verification failed, then the progress skip to the next lap.

After pressing the button of start fill, the website would display an alert message, so I use function switch_to_alert().accept() to confirm this alert message.

for i in range(3):
try:
input_id=name+str(i)
print(input_id)
driver.find_element_by_id(input_name).click()
enter_step1()
driver.switch_to_alert().accept()
print('success')
enter_step2()
# sunmit()
except:
print('fail')
# driver.switch_to_alert().accept(

completion

regardless of various verification problems, also unable to affect the programming implementation.

Code

import requests
from selenium import webdriver
import time
url='https://webap1.kshs.kh.edu.tw/kshsSSO/publicWebAP/bodyTemp/index.aspx'
driver=webdriver.Chrome("./chromedriver")
driver.get(url)
def enter_step1():
print('step1')
driver.find_element_by_id('ContentPlaceHolder1_txtId').send_keys('(身分證字號)')
driver.find_element_by_id('ContentPlaceHolder1_btnId').click()

def enter_step2():
print('step2')
driver.find_element_by_id('ContentPlaceHolder1_rbType_1').click()
driver.find_element_by_xpath('//[@id="ContentPlaceHolder1_ddl1"]/option[3]').click()
driver.find_element_by_xpath('//[@id="ContentPlaceHolder1_ddl2"]/option[4]').click()
driver.find_element_by_xpath('//[@id="ContentPlaceHolder1_ddl3"]/option[2]').click()

def sunmit():
print('submit')
driver.find_element_by_id('ContentPlaceHolder1_btnId0').click()
id='ContentPlaceHolder1_RadioButtonList1_'
for i in range(3):
try:
input_id=name+str(i)
print(input_id)
driver.find_element_by_id(input_name).click()
enter_step1()
driver.switch_to_alert().accept()
print('success')
enter_step2()
sunmit()
except:
print('fail')
time.sleep(5)
driver.quit()

--

--