这里以12306为例子:日期2018-02-02从广州到成都在动车组票为例。实现业务需求功能如下:
实现思路:
1:首先使用phantomjs来获取搜索结果页面。然后截图
2:然后从截图中获取动车车次和是否有票数据。
3:如果没有票就回到第1步继续查票。直到有票才打开12306网站。
4:动态输入用户名密码。然后手工打码。提交登陆请求。
5:最后动态选择条件实现搜索。最后收到购票。
下面是完整代码:
#!/usr/bin/pythyon
# _*_ coding:utf-8 _*_
# author: Robinn
import os
import sys
import time
import base64
from PIL import Image
from io import BytesIO
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.support import expected_conditions as EC
from selenium.common.exceptions import NoSuchElementException
from selenium.webdriver.common.by import By
reload(sys)
sys.setdefaultencoding("utf-8")
myemail = "cm9szAw"
mypws = "cmauA="
#构建应用
phantomjsURL = "/phantomjs-2.1.1-windows/bin/phantomjs.exe"
while True:
driver = webdriver.PhantomJS(executable_path=phantomjsURL)
driver.maximize_window()
time.sleep(2)
#发送搜票请求
driver.get('https://kyfw.12306.cn/otn/leftTicket/init')
#起始站
driver.find_element_by_xpath('//*[@id="fromStationText"]').click()
driver.find_element_by_xpath('//*[@id="ul_list1"]/li[9]').click()
#driver.find_element_by_xpath('//*[@id="fromStationText"]').send_keys(u'广州')
#目标站
driver.find_element_by_xpath('//*[@id="toStationText"]').click()
driver.find_element_by_xpath('//*[@id="ul_list1"]/li[7]').click()
#driver.find_element_by_xpath('//*[@id="toStationText"]').send_keys(u'成都')
# #出行日期
driver.find_element_by_xpath('//*[@id="train_date"]').click()
driver.find_element_by_xpath('/html/body/div[30]/div[2]/div[2]/div[2]/div').click() #2018-02-02
#driver.find_element_by_xpath('/html/body/div[30]/div[2]/div[2]/div[3]/div').click() #2018-02-03
#driver.find_element_by_xpath('/html/body/div[30]/div[2]/div[2]/div[3]/div').click() #2018-02-03
#driver.find_element_by_xpath('/html/body/div[30]/div[2]/div[2]/div[19]/div').click() #2018-02-19
#driver.find_element_by_xpath('//*[@id="train_date"]').send_keys('2018-02-02')
#选择动车
driver.find_element_by_xpath('/html/body/div[5]/div[5]/div[2]/div[2]/div[2]/ul/li[2]/input').send_keys(Keys.SPACE)
#发送请求
if driver.find_element_by_xpath('/html/body/div[5]/div[5]/div[2]/div[2]/div[2]/ul/li[2]/input').is_selected():
print(u"已经选择日期【2018-02-02】从【广州】到【成都】的【D-动车组】票,并发出票务请求......")
driver.find_element_by_xpath('//*[@id="query_ticket"]').click()
sreach_window = driver.current_window_handle
print(u"发送搜票请求完成。正在分析......")
time.sleep(5)
driver.save_screenshot('screen_shoot.jpg')
driver.quit()
#裁剪动车次
img = Image.open("screen_shoot.jpg")
target_box = (201,285,260,616)
target_img = img.crop(target_box)
target_img.save("target_1.jpg")
#检索动车车次
from aip import AipOcr
APP_ID = '1045346'
API_KEY = 'M73AwH6k74rH'
SECRET_KEY = 'G4DlQN6EE5evgNt1'
def get_img_content(img_filepath):
with open(img_filepath,"rb") as f:
return f.read()
client1 = AipOcr(APP_ID, API_KEY, SECRET_KEY)
img = get_img_content("target_1.jpg")
res = client1.basicGeneral(img)
str = ""
for line in res:
if type(res[line]) == list:
words = res[line]
for x in words:
str = str+x["words"]+","
result1 = str[:-1]
#裁剪是否有票
img = Image.open("screen_shoot.jpg")
target_box = (648,285,692,616)
target_img = img.crop(target_box)
target_img.save("target_2.jpg")
#检查是否有票
client2 = AipOcr(APP_ID, API_KEY, SECRET_KEY)
img = get_img_content("target_2.jpg")
res = client2.basicGeneral(img)
str = ""
for line in res:
if type(res[line]) == list:
words = res[line]
for x in words:
str = str+x["words"]+","
result2 = str[:-1]
list_checi = result1[3:].split(",")
list_ispiao = result2.split(",")
print('\033[1;32;40m')
print("==========================================================================")
for num in range(len(list_checi)):
print(u"【"+list_checi[num] + u"】 动车车次 " + list_ispiao[1][num] + u" 票")
print("==========================================================================")
print('\033[0m')
cnt = list_ispiao[1].count(u"有")
if cnt>=1:
driver.quit()
#窗口抖动提示
import random
import win32gui
import win32api,win32con
import ctypes
class RECT(ctypes.Structure):
_fields_ = [('left', ctypes.c_int),
('top', ctypes.c_int),
('right', ctypes.c_int),
('bottom', ctypes.c_int)]
rect = RECT()
HWND = win32gui.GetForegroundWindow()
ctypes.windll.user32.GetWindowRect(HWND, ctypes.byref(rect))
for i in range(2,200):
win32gui.SetWindowPos(HWND, None, rect.left+5*random.randint(1,i), rect.top-5*random.randint(1,i), rect.right-rect.left, rect.bottom-rect.top, win32con.SWP_NOSENDCHANGING|win32con.SWP_SHOWWINDOW)
win32gui.SetWindowPos(HWND, None, rect.left, rect.top, rect.right-rect.left, rect.bottom-rect.top, win32con.SWP_NOSENDCHANGING|win32con.SWP_SHOWWINDOW)
#打开浏览器购票
url = "https://kyfw.12306.cn/otn/login/init"
wd = webdriver.Chrome(r"\Python\12306\chromedriver.exe")
wd.get(url)
time.sleep(5)
email = WebDriverWait(wd,timeout=10).until(EC.presence_of_element_located((By.NAME,'loginUserDTO.user_name')),message='loading timeout')
email.send_keys(base64.decodestring(myemail))
passwd = WebDriverWait(wd,timeout=10).until(EC.presence_of_element_located((By.NAME,'userDTO.password')),message='loading timeout')
passwd.send_keys(base64.decodestring(mypws))
time.sleep(15)
wd.find_element_by_xpath('//*[@id="selectYuding"]/a').click()
wd.maximize_window()
time.sleep(5)
#选择条件
wd.find_element_by_xpath('//*[@id="fromStationText"]').click()
wd.find_element_by_xpath('//*[@id="ul_list1"]/li[9]').click()
wd.find_element_by_xpath('//*[@id="toStationText"]').click()
wd.find_element_by_xpath('//*[@id="ul_list1"]/li[7]').click()
wd.find_element_by_xpath('//*[@id="train_date"]').click()
wd.find_element_by_xpath('/html/body/div[30]/div[2]/div[2]/div[2]/div').click()
wd.find_element_by_xpath('/html/body/div[5]/div[5]/div[2]/div[2]/div[2]/ul/li[2]/input').send_keys(Keys.SPACE)
if wd.find_element_by_xpath('/html/body/div[5]/div[5]/div[2]/div[2]/div[2]/ul/li[2]/input').is_selected():
wd.find_element_by_xpath('//*[@id="query_ticket"]').click()
break
else:
driver.quit()
continue
#退出应用
sys.exit(0)
|
上面代码是我临时写的。没有很好的封装和优化。一个刷票的思路。仅供参考。
注:本文内容均系原创。如需转载分享请标明出处。