
Tạo Bot Đăng Kí Học Tự Động Ở Trường Dễ Dàng (P2)
Không biết hiện tại các bạn đã thi cuối học kì xong hết chưa nhỉ? Chúc các bạn có một mùa thi thật tốt nhé! Sau khi viết xong phần 1 thì mình nhận được phản hồi rất tích cực từ các bạn đọc vì thế hôm nay ngày lành tháng đẹp mình quyết định viết tiếp phần 2 cũng là phần kết cho bài tạo bot để đăng kí học
Phần 1 ở đây nhé các bạn,
Mình xin nhắc lại mục tiêu và các bước chúng ta cần làm:
- Mục tiêu:
- Tạo bot giả lập hành vi của người dùng để đăng kí học tự động
- Bot phải hoạt động thật nhanh và chính xác
- Các bước cần làm
- Vượt captcha (phần 1 chúng ta đã làm để nhận diện chứ số từ captcha thành công)
- Giả lập hành vi người dùng để đăng kí
Ok, giờ cùng bắt tay vào làm cùng mình nhé 😀
1. Vượt captcha
Chúng ta cùng nhìn lại giao diện đăng nhập chứa captcha một lần nữa nhé:
Để vượt captcha này sử dụng model ai mà chúng ta đã làm được ở bài trước thì các bước làm sẽ như sau:
- B1: Load model ai
- B2: Download ảnh captcha đưa vào model để nhận diện
- B3: Nhập captcha nhận diện được
- B4: Nếu captcha nhận diện sai load lại trang và thực hiện lại từ B2
Đầu tiên chúng ta sẽ tạo một file load_model.py để load model
import tensorflow as tf
import tflearn
from tflearn.layers.conv import conv_2d, max_pool_2d
from tflearn.layers.core import input_data, dropout, fully_connected
from tflearn.layers import regression
from tflearn.data_utils import to_categorical
import cv2
import numpy as np
def load_model():
IMG_SIZE = 75
N_CLASSES = 9
LR = 0.001
tf.reset_default_graph()
network = input_data(shape=[None, IMG_SIZE, IMG_SIZE, 1]) #1
network = conv_2d(network, 32, 3, activation='relu') #2
network = max_pool_2d(network, 2) #3
network = conv_2d(network, 64, 3, activation='relu')
network = max_pool_2d(network, 2)
network = conv_2d(network, 32, 3, activation='relu')
network = max_pool_2d(network, 2)
network = conv_2d(network, 64, 3, activation='relu')
network = max_pool_2d(network, 2)
network = conv_2d(network, 32, 3, activation='relu')
network = max_pool_2d(network, 2)
network = conv_2d(network, 64, 3, activation='relu')
network = max_pool_2d(network, 2)
network = fully_connected(network, 1024, activation='relu') #4
network = dropout(network, 0.8) #5
network = fully_connected(network, N_CLASSES, activation='softmax')#6
network = regression(network)
model = tflearn.DNN(network) #7
model.load('model/mymodel.tflearn')
return model
Tiếp theo chúng ta tạo thêm file decode_captcha.py để chuyển ảnh captcha thành số:
import numpy as np
import cv2
def find_location(img):
#img = cv2.imread(url, 0)
#img = cv2.cvtColor(img)
blur = cv2.GaussianBlur(img,(5,5),0)
thresh = cv2.adaptiveThreshold(blur,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C,cv2.THRESH_BINARY_INV,11,2)
horizal = thresh
vertical = thresh
scale_height = 20
scale_long = 15
long = int(img.shape[1]/scale_long)
height = int(img.shape[0]/scale_height)
horizalStructure = cv2.getStructuringElement(cv2.MORPH_RECT, (long, 1))
horizal = cv2.erode(horizal, horizalStructure, (-1, -1))
horizal = cv2.dilate(horizal, horizalStructure, (-1, -1))
verticalStructure = cv2.getStructuringElement(cv2.MORPH_RECT, (1, height))
vertical = cv2.erode(vertical, verticalStructure, (-1, -1))
vertical = cv2.dilate(vertical, verticalStructure, (-1, -1))
mask = vertical + horizal
contours, hierarchy = cv2.findContours(mask,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
table = []
for cnt in contours:
x, y, w, h = cv2.boundingRect(cnt)
#print((x,y,w,h))
if h > 1 and w > 1:
square = cv2.contourArea(cnt)
table.append((square,x,y,w,h))
table.sort(reverse=True)
#print(table[0])
return table[0]
def add_matrix(image, mark):
(a,b) = mark.shape
(x,y) = image.shape
delta_y = int((b-y)/2)
delta_x = int((a-x)/2)
for i in range(a):
for j in range(b):
if(j>delta_y and j<y+delta_y and i>delta_x and i<x+delta_x):
if 0 != image[i-delta_x][j-delta_y]:
mark[i][j]=255
else:
mark[i][j]=0
return mark
def decode(img, model):
delta=3
location = find_location(img)
start = location[1]+delta
diff = int((location[3] - 2*delta)/5)
rs = ""
for i in range(5):
sub = img[location[2]:location[2]+location[4],start:start+diff]
mark = np.zeros((75,75))
start = start+diff
sub_img = add_matrix(sub,mark)
sub_img = sub_img.reshape(-1,75,75,1)
result = model.predict(sub_img)
result = np.argmax(result, axis=-1)
rs = rs + str(result[0])
return rs
Gần xong rồi, tiếp chúng ta sẽ tạo file main.py để chạy project nào 😀
from selenium import webdriver
import time
from load_model import load_model
from utils import stringToRGB
from decode_captcha import decode
import signal
from contextlib import contextmanager
from selenium.webdriver.common.keys import Keys
from webdriver_manager.chrome import ChromeDriverManager
import os
USERNAME = ""
PASSWORD = ""
# đường dẫn tới web đăng ký
URL = ""
# mã lớp đăng ký
subjects = []
def login():
model = load_model()
driver = webdriver.Chrome(
executable_path=ChromeDriverManager().install(), options=options
)
driver.set_script_timeout(10)
driver.get(URL)
time.sleep(0.5)
current_url = URL
while current_url == URL:
captcha_code = ""
try:
# nhập username
driver.find_element_by_xpath('//*[@id="tbUserName"]').clear()
driver.find_element_by_xpath('//*[@id="tbUserName"]').send_keys(USERNAME)
ele_captcha = driver.find_element_by_xpath(
'//*[@id="ccCaptcha_IMG"]')
# get the captcha as a base64 string
img_captcha_base64 = driver.execute_async_script("""
var ele = arguments[0], callback = arguments[1];
ele.addEventListener('load', function fn(){
ele.removeEventListener('load', fn, false);
var cnv = document.createElement('canvas');
cnv.width = this.width; cnv.height = this.height;
cnv.getContext('2d').drawImage(this, 0, 0);
callback(cnv.toDataURL('image/png').substring(22));
}, false);
ele.dispatchEvent(new Event('load'));
""", ele_captcha)
image = stringToRGB(img_captcha_base64)
captcha_code = decode(image, model)
driver.find_element_by_xpath('//*[@id="tbPassword_CLND"]').click()
driver.find_element_by_xpath(
'//*[@id="tbPassword"]').send_keys(PASSWORD)
driver.find_element_by_xpath(
'//*[@id="ccCaptcha_TB_I"]').send_keys(captcha_code)
driver.find_element_by_xpath('//*[@id="ctl01"]/p[4]/button').click()
time.sleep(0.5)
current_url = driver.current_url
except Exception as e:
print(e)
driver.get(URL)
time.sleep(50)
return driver
Để lấy được giá trị xpath thì chúng ta mở chế độ developer tool trên chrome và làm như sau:
2. Giả lập hành vi người dùng để đăng ký
Đăng nhập xong coi như chúng ta đã gần như hoàn thành project. Bước còn lại chỉ là sử dụng selenium để nhập mã lớp học và gửi đăng ký. Công đoạn này không có gì phức tạp nên mình sẽ để bạn đọc tự hoàn thiện nhé.
Dưới đây mình sẽ để các thông tin về xpath của các trường cần thiết:
- xpath ô nhập mã lớp học: //*[@id=”ctl00_ctl00_ASPxSplitter1_Content_ContentSplitter_MainContent_ASPxCallbackPanel1_tbDirectClassRegister_I
- xpath button gửi đăng ký: //*[@id=”ctl00_ctl00_ASPxSplitter1_Content_ContentSplitter_MainContent_ASPxCallbackPanel1_btSendRegister”]
- xpath button xác nhận gửi đăng ký: //*[@id=”ctl00_ctl00_ASPxSplitter1_Content_ContentSplitter_MainContent_ASPxCallbackPanel1_pcYesNo_pcYesNoBody1_ASPxRoundPanel1_btnYes”]
Tạm kết
Tới đây các bạn đã có thể tự hoàn thành bot đăng ký học cho riêng mình rồi =))
Trong lúc làm mà có gặp vấn đề gì các bạn có thể để lại comment tại đây hoặc liên hệ với mình qua facebook: Pham Hung mình sẽ hỗ trợ các bạn trong khả năng có thể.
Thanks for reading ^^
Post Comment