Last active
May 30, 2021 08:23
-
-
Save arthur-tomsjj/925f60313fad7c83bd8cf5dbe4eb7603 to your computer and use it in GitHub Desktop.
拓元自動購票系統
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from selenium import webdriver | |
from selenium.webdriver.common.keys import Keys | |
from selenium.webdriver.support.ui import Select | |
from PIL import Image | |
from bs4 import BeautifulSoup | |
import cv2 | |
import requests | |
import numpy as np | |
import pytesseract | |
import time | |
import os | |
url = "https://tixcraft.com/activity/detail/21_Eclipse" | |
driver = webdriver.Chrome('D:\\PythonLab\\chromedriver_win32\\chromedriver.exe') | |
driver.get(url) | |
#下拉視窗 | |
def scroll(num): | |
js="var q=document.documentElement.scrollTop = "+str(num) | |
driver.execute_script(js) | |
time.sleep(1) | |
scroll(500) | |
#點開購票 | |
elem_operate_1 = driver.find_element_by_xpath("//*[@id='content']/div/div/ul/li[1]/a") | |
elem_operate_1.click() | |
time.sleep(2) | |
#立即購票 | |
elem_operate_2 = driver.find_element_by_xpath("//*[@id='gameList']/table/tbody/tr/td[4]/input") | |
elem_operate_2.click() | |
time.sleep(1) | |
#新網頁下拉 | |
scroll(500) | |
#尋找還能購買的座位 | |
seat_number = 1 | |
while 1: | |
elem_choose = driver.find_element_by_xpath("/html/body/div/div[2]/div[2]/div/div[2]/div[2]/div[2]/ul["+str(seat_number)+"]/li") | |
if elem_choose.text.find("已售完") < 0: | |
break | |
seat_number += 1 | |
elem_choose.click() | |
time.sleep(1) | |
#到購買頁面 | |
#下拉視窗 | |
scroll(400) | |
#選擇票數 | |
elem_select_num = driver.find_element_by_xpath("//*[@id='TicketForm_ticketPrice_10']") | |
Select(elem_select_num).select_by_value("1") | |
#下載驗證 | |
#無法使用以下圖片下載法,因為下載來後會因requests再次訪問網站使載到的驗證圖改變 | |
#html = driver.page_source | |
#page = BeautifulSoup(html,'html.parser') | |
#captcha_IMG = page.find(id = 'yw0') | |
#IMG_url = "https://tixcraft.com" + captcha_IMG['src'] | |
#print() | |
#IMG_NAME = IMG_url.split('=') | |
#fname = 'captcha/'+IMG_NAME[-1]+'.png' | |
#data = requests.get(IMG_url) | |
#with open(fname,'wb') as f: | |
# f.write(data.content) | |
# f.close() ''' | |
#要用截圖大法 | |
path = 'captcha/screenshot.png' | |
driver.save_screenshot(path) # 先將目前的 screen 存起來 | |
time.sleep(1) | |
element = driver.find_element_by_xpath("//*[@id='yw0']") | |
location = element.location # 取得圖片 element 的位置 | |
size = element.size # 取得圖片 element 的大小 | |
left = location['x']+75 # 決定上下左右邊界 | |
top = location['y']-370 | |
right = location['x'] + size['width']+100 | |
bottom = location['y'] + size['height']-350 | |
image = Image.open(path) # 將 screen load 至 memory | |
image = image.crop((left,top,right,bottom)) # 根據位置剪裁圖片 | |
image.save('captcha/captcha'+'.png', 'png') # 重新儲存圖片為 png 格式 | |
#抓下驗證後,用tesseract圖片辨識 | |
# 灰度 0-255 255-當前灰度值 | |
img = cv2.imread('captcha/captcha.png') | |
imginfo = img.shape #取得圖片size的長寬 (長,寬) ,tuple型態 | |
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) #opencv的彩色轉灰階 | |
height = imginfo[0] | |
width = imginfo[1] | |
center = (width//2,height//2) #取得圖片中心位置 | |
M = cv2.getRotationMatrix2D(center,-5,1.0) #以中心順時鐘旋轉5度,負為順,正為逆;1.0 為縮放 | |
gray1 = cv2.warpAffine(gray,M,(width,height)) #warpAffine為圖片旋轉或平移的式子 參數: 圖檔, 旋轉or平移參數, (長寬) | |
dst = np.zeros((height, width, 1), np.uint8) | |
for i in range(height): #顏色反轉 | |
for j in range(width): | |
grayPixel = 255 - gray1[i, j] | |
dst[i, j] = grayPixel | |
cv2.imwrite('captcha/captcha_gray.png',dst) #OpenCV 圖片儲存的方法 | |
#進行圖片二元化 | |
picture = Image.open('captcha/captcha_gray.png') | |
gray = picture.convert('L') | |
table = [] | |
threshold = 115 | |
for i in range(256): | |
if i < threshold: | |
table.append(0) | |
else: | |
table.append(1) | |
binary = gray.point(table,'1') | |
binary.save('captcha/captcha_binary.png') #PIL 圖片儲存方法 | |
#圖片識別 | |
Pic_read = Image.open('captcha/captcha_binary.png') | |
pytesseract.pytesseract.tesseract_cmd = r'D:\PythonLab\OCR_database\tesseract.exe' | |
text = pytesseract.image_to_string(Pic_read) | |
#進行驗證碼輸入 | |
input_captcha = driver.find_element_by_xpath("//*[@id='TicketForm_verifyCode']") | |
input_captcha.send_keys(text) | |
try: | |
driver.switch_to_alert().accept() #若出現彈出視窗,點掉 | |
except Exception as e: | |
input_captcha.send_keys(text) | |
pass | |
#點選"我同意" | |
accept = driver.find_element_by_xpath("//*[@id='TicketForm_agree']") | |
accept.click() | |
#提交 | |
confirm = driver.find_element_by_xpath("//*[@id='ticketPriceSubmit']") | |
confirm.click() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment