Автоматическая передача данных о температуре тела в температурную систему школы

Мотивация

Поскольку случилась пандемия Covid-19, в моей школе требовалось, чтобы каждый ученик сообщал температуру тела в систему отчетности о температуре в период с шести утра до восьми утра каждый божий день, чтобы избежать распространения болезни/вируса. Я считаю эту политику действительно ненужной и бесполезной. Потому что реальную температуру тела никто не сообщит, вместо этого она приносит неприятности каждому студенту, потому что все ленивы, в том числе и я. Важно то, что если вы забудете сообщить температуру, то получите предупреждение.

Я абсолютно не приемлю это хлопотное требование. Поэтому я решаю написать веб-краулер, который будет автоматически сообщать о температуре тела.

В начале это было очень успешно; Я использую веб-краулер, чтобы сообщать о температуре. Я использовал его, чтобы сообщить свою температуру, как обычно, поэтому я обнаружил, что он не может успешно сообщать о температуре, он может сообщать только вручную. Я увидел интерфейс, который меня действительно ошеломил, когда я открыл веб-сайт.

Честно говоря, я немного удивлен и ошарашен одновременно, когда увидел этот интерфейс, поэтому начал думать над решением.

Начать делать

Идеи 1

язык разработки: python

с помощью пакета расширения:

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

сначала я использую requests для обхода веб-сайта, а затем помещаю его в BeautifulSoup для анализа.

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

Теперь я просканировал веб-сайт, и теперь моя миссия состоит в том, чтобы позволить компьютеру проверить правильный вариант.

Подход, при котором могут возникнуть проблемы с получением проверочного номера.

веб-сайт после вскрытия BeautifulSoup, затем используйте подход find$=(id=’ContentPlaceHolder1_lb’), чтобы найти область проверочного номера из HTML, и сохраните tag_verification_num.string (проверочный номер) в переменной tag_verification_num. Но теперь возникает проблема, когда я печатаю переменную tag_verification_num, значение нулевой.

Решение

После анализа веб-сайта через beautifulsoup используйте подход find$=(id=’ContentPlaceHolder1_lb’), чтобы найти область отображения проверочного номера, и после сохранения ag_verification_num.string(проверочный номер) в переменную tag_verification_num, тип перехода в строку, затем я нахожу этот тип перехода метки диапазона в строка, 65-й символ которой является проверочным номером.

Затем я сохраняю его в переменных для последующего использования.

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

Теперь я получил проверочный номер, затем мне нужно получить номера каждого варианта проверки.

HTML-структура параметра проверки использовала метку диапазона для переноса параметра ввода и метки номера отображаемого параметра.

Итак, я использую подход find.(id=’ContentPlaceHolder1_RadioButtonList1'), чтобы найти входную метку и ее родительский диапазон, затем сохраняю ее в переменную tag_verification, а затем использую подход tag_verification.find_all(‘input’), чтобы найти все входные метки в диапазоне.

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

Неверный подход к получению значения параметра

После того, как вы прошли подход tag_verification.find_all(‘input’), чтобы получить все метки ввода в метке диапазона, затем используйте цикл for i in tag_verification_input: для доступа к значению каждой метки ввода, но у меня есть проблема, вероятно, выше этого момента, которая отображает ноль, когда я печатаю переменную i.

Решение

здесь также можно использовать то же решение, что и выше, преобразовать тип входной метки в строку, а найти значение — это первые несколько символов в строке, чтобы я мог получить номера вариантов проверки.

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]//驗證選項的數字

Поскольку метка ввода в переменной tag_verification_input заменяется переменной i в цикле for, поэтому переменная i заменит параметр проверки ниже.

Теперь я получил проверочный номер, а также получил номер каждой опции, следующим шагом я хочу сделать программирование, чтобы определить, какое количество опций равно проверочному номеру.

Я добавил условные выражения в цикл for i in tag_verification_input: , чтобы определить, равен ли 121-й символ переменной char, которую я трансформирую в строку, переменной num_verification .

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

Я уже знаю входную метку, которая соответствует проверочному номеру, теперь мне нужно знать атрибут этой входной метки, чтобы я мог использовать подход find_element_by_name() для управления веб-драйвером, чтобы проверить правильный вариант. если использовать подход большинства интуиций num_input=i.name , значение переменной num_input равно нулю, как и выше. Поэтому также необходимо преобразовать тип переменной i в строку, а затем num_input[57:99] сохранит символы в диапазоне от 59-го до 99-го, что является именем переменной i .

После того, как я получил имя метки ввода, я могу управлять веб-драйвером, чтобы проверить правильный вариант.

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()

Улучшать

Мотив 2.0

2021/4/21 Менеджер школьного веб-сайта снова обновил систему отчетов о температуре тела.

Функция проверки меняется, чтобы ответить на непредсказуемый вопрос, это обновление снова меня удивляет. Кстати, я предлагаю в следующий раз обновить функцию проверки, чтобы решить исчисление.

Идея 2.0

причудливый

Моя первоначальная идея состоит в том, что менеджер школьного веб-сайта задаст вопрос о базовых знаниях, как все знают, поэтому я планирую использовать запросы функций и BeautifulSoup, чтобы получить вопрос, а затем через Википедию найти правильный ответ, наконец, определить, являются ли оба ответы из Википедии и системы проверки совпадают.

проблема: после изменения подхода к проверке я обнаружил, что requests и beautifulsoup бесполезны для анализа любого атрибута ярлыка.

Решение: нет возможности — нет решения.

исчерпывающее решение

впоследствии я изобретаю подход, который позволяет игнорировать любое значение метки и контрольных вопросов. Это весь атрибут id входной метки, передняя часть строки которого равна ContentPlaceHolder1_RadioButtonList1_ , а последнее число — это вариант буфера, например:

первый вариант:ContentPlaceHolder1_RadioButtonList1_0
второй вариант:ContentPlaceHolder1_RadioButtonList1_1
третий вариант:ContentPlaceHolder1_RadioButtonList1_2

Затем я могу следовать правилам, чтобы попробовать каждый вариант, чтобы решить эту проблему.

Функция

Для удобства я бы поставил функцию представлять любую операцию, кроме проверки.

  1. enter_step1()

Функция: введите идентификатор удостоверения и нажмите кнопку отправки.

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()

функция:заполнение температуры теласостояние и статус посещаемости

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()

функция: нажмите кнопку завершения заполнения.

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

подтверждение

Во-первых, удалите все последние числа, представляющие номер опции, из строки атрибута id и сохраните эту строку в переменной id.

id='ContentPlaceHolder1_RadioButtonList1_'

Потому что количество опционов будет меняться каждый день, но по моим наблюдениям до четырех. Поэтому я использую цикл for i in range(3) и объявил переменную, равную name+str(i) , которая может через цикл for получить каждое атрибут переменной i входной метки, а затем поместить эту переменную в функцию find_element_by_id() , пробовать каждый круг. Поскольку, если проверка не пройдена, прогресс продолжает сообщать о температуре тела, он получит ошибку, поэтому я должен установить обработку исключений в цикле for, если проверка не удалась, то прогресс переходит к следующему кругу.

После нажатия кнопки начала заполнения веб-сайт отобразит предупреждающее сообщение, поэтому я использую function switch_to_alert().accept() для подтверждения этого предупреждающего сообщения.

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(

завершение

независимо от различных проблем с проверкой, также не может повлиять на реализацию программирования.

Код

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()