zhangqf преди 6 години
родител
ревизия
08f95b9c2d
променени са 5 файла, в които са добавени 1192 реда и са изтрити 1 реда
  1. 34 1
      src/AirasiaWeb.py
  2. 22 0
      src/entity/RelationInfo.py
  3. 249 0
      src/order/RelationOrder.py
  4. 833 0
      src/test/AKBooker_Agent.py
  5. 54 0
      src/test/RelationHtmlTest3.py

+ 34 - 1
src/AirasiaWeb.py

@@ -6,6 +6,7 @@ import json
 import time
 import _thread
 from order.OrderServer import OrderServer
+from order.RelationOrder import RelationOrder
 from utils.CallbackOrderUtils import CallbackOrderUtils as call
 import logging
 
@@ -204,10 +205,42 @@ class AirasiaAgentWeb(tornado.web.RequestHandler):
         logging.info('-------------------end time(s)-------------------')
         end = time.clock()
         logging.info("read: %f s" % (end - start))
+
+#AK订单关联
+class AirasiaRelation(tornado.web.RequestHandler):
+    #添加一个处理get请求方式的方法
+    def get(self):
+        #向响应中,添加数据
+        respEntity = {'attachment':'AK订单关联','status':'-1'}
+        self.write(respEntity)
+    def post(self):
+        param = self.request.body.decode('utf-8')
+        logging.info('AK订单关联:'+param)
+        #第一步 解析数据并登录
+        order_relation = RelationOrder(param)
+        if order_relation.checkParams() == False:
+            respEntity = {'attachment':'AK订单关联参数错误:'+order_relation.msg,'status':'100'}
+            self.write(respEntity)
+            return
+        if order_relation.Login() == False:
+            respEntity = {'attachment':'AK订单关联:登录失败','status':'100'}
+            self.write(respEntity)
+            return
+        #第二步 查找订单并校验数据
+        relationHtml = order_relation.lookupOrder()
+        #第三步 进行关联并获取关联结果
+        if order_relation.RelationOrder(relationHtml):
+            respEntity = {'attachment':'AK订单关联_成功','status':'200'}
+            self.write(respEntity)
+            return
+        respEntity = {'attachment':'AK订单关联_失败','status':'100'}
+        self.write(respEntity)
+        
+        
 if __name__ == '__main__':
     config_log()
     #创建一个应用对象
-    app = tornado.web.Application([(r'/akOrder',AirasiaWeb),(r'/akAgOrder',AirasiaAgentWeb),(r'/akOrderTest',AirasiaWebTest)])
+    app = tornado.web.Application([(r'/akOrder',AirasiaWeb),(r'/akAgOrder',AirasiaAgentWeb),(r'/akOrderTest',AirasiaWebTest),(r'/orderRelation',AirasiaRelation)])
     #绑定一个监听端口
     app.listen(8888)
     #启动web程序,开始监听端口的连接

+ 22 - 0
src/entity/RelationInfo.py

@@ -0,0 +1,22 @@
+# -*- coding: utf-8 -*-
+
+# 订单关联实体类
+class OrderRelationEntity() :
+    def __init__(self):
+        self.singleAccount = ""; # 出单账户
+        self.singleAccountPassWord=""; #出单账户密码
+        self.orderNo = ""; # 出单号码
+        self.passengers = [];
+    def __repr__(self):
+        return  repr(self.singleAccount,self.singleAccountPassWord,self.orderNo,self.passengers);
+
+
+# 已经注册的乘客信息
+class PassengerEntity():
+    def __init__(self):
+        self.firstName = "" # 名称
+        self.lastName  = "" #姓
+        self.bigNo = ""; # 注册账户的big 号码
+        self.birthday = "";#生日
+    def __repr__(self):
+        return  repr(self.firstName,self.lastName,self.bigNo,self.birthday);

+ 249 - 0
src/order/RelationOrder.py

@@ -0,0 +1,249 @@
+#-*- coding:utf-8 -*-
+import json
+import requests
+from lxml import etree
+from pyquery import PyQuery as pq
+from entity.RelationInfo import OrderRelationEntity,PassengerEntity
+import logging
+    
+# 订单关联
+class RelationOrder():
+    def __init__(self,params):
+        self.josn_str = params
+        # 转换为实体类字段
+        self.orderRelation = OrderRelationEntity();
+        self.orderRelation.__dict__ = json.loads(self.josn_str)
+        self.passengers = self.orderRelation.passengers
+        self.session = requests.session()
+        self.__VIEWSTATE = ''
+        #请求头
+        self.headers = {
+            'Accept-Encoding': 'gzip',
+            "Content-Encoding": "gzip, deflate, sdch",
+            "Accept-Language": "zh-CN,zh;q=0.8,en;q=0.6",
+            "Upgrade-Insecure-Requests": "1",
+            "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
+            "User-Agent":"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.146 Safari/537.36",
+        }
+        self.session.headers.update(self.headers)
+        #登录提交参数
+        self.logindata = {
+            "__VIEWSTATE":"/wEPDwUBMGRktapVDbdzjtpmxtfJuRZPDMU9XYk=",
+            "__EVENTARGUMENT":"",
+            "__EVENTTARGET":"ControlGroupLoginAgentView$AgentLoginView$LinkButtonLogIn",
+            "ControlGroupLoginAgentView$AgentLoginView$TextBoxUserID":"CNTRIPTOPK_ADMIN",
+            "ControlGroupLoginAgentView$AgentLoginView$PasswordFieldPassword":"Tripto123",
+            "pageToken":"",
+            "TimeZoneDiff":"480"
+        }
+        self.msg = '';
+        self.isok = True;
+    #校验参数是否正确
+    def checkParams(self):
+        if len(self.orderRelation.orderNo) < 1:
+            #订单号不能为空
+            self.msg = '订单号不能为空';
+            return False;
+        if len(self.orderRelation.singleAccount) < 1:
+            #账号不能为空
+            self.msg = '账号不能为空';
+            return False;
+        if len(self.orderRelation.singleAccountPassWord) < 1:
+            #密码不能为空
+            self.msg = '密码不能为空';
+            return False;
+        if len(self.orderRelation.passengers) < 1:
+            #关联人不能为空
+            self.msg = '关联人不能为空';
+            return False;
+        return True;
+    
+    def Login(self):
+          #添加代理IP
+#         cl = call()
+#         proxyurl = cl.getProxyIP()
+#         proxy_handler = {
+#             'http': 'http://'+proxyurl,
+#             'https': 'https://'+proxyurl,
+#         }
+#         self.session.proxies = proxy_handler
+#         logging.info('IP:'+proxyurl)
+
+
+        res = self.session.get("https://www.airasia.com/my/en/login/travel-agent.page")
+        page = etree.HTML(res.text)
+        self.logindata['__VIEWSTATE'] = page.xpath("//input[@name='__VIEWSTATE']/@value")[0]
+        self.__VIEWSTATE = self.logindata['__VIEWSTATE']
+        print(self.__VIEWSTATE)
+        logging.info('__VIEWSTATE:'+self.__VIEWSTATE)
+        
+        logindata = {
+            "__EVENTARGUMENT": "",
+            "__EVENTTARGET": "ControlGroupLoginAgentView$AgentLoginView$LinkButtonLogIn",
+            "ControlGroupLoginAgentView$AgentLoginView$TextBoxUserID": "CNTRIPTOPK_ADMIN",
+            "ControlGroupLoginAgentView$AgentLoginView$PasswordFieldPassword": "Tripto123",
+            "pageToken": "",
+            "TimeZoneDiff": "480"
+        }
+        self.session.cookies['i10c.bdddb'] = 'c2-f0103ZLNqAeI3BH6yYOfG7TZlRtCrMwzKDQfPMpdrBiHtspjoz4hG1gmlRTCqoP3KDqfQuYkuTrJ0zjBTuTfS8ZkqMupqjxVKDq7gmYkJNoptsolozTpvkQUSMtHlpVtKDQfPM0u5KY8oxo6uXRaGVZkqo8pgTsvP8rINHdKESnj9soBo01fLvZkQMtHHdplG8qkKNBiESNCtxyuZZBaGvZlOPoHQjxvly9WxxYkJNopssolozT4slZkqMupltWqPDGuoc0BESnCuVjBt3OftxZkqMtrloxBjRlkPHeIESnIoxRCozTaGVZkqk9c8jxvKEOfPMdfJ5nCtxjGUuTFBve3czUtRjxvKEOiKMDfJSCeoxo6uXOfGqelSMtHltY'  
+        res = self.session.post("https://booking2.airasia.com/LoginAgent.aspx", data=logindata, verify=False, timeout=60)
+        agentHomeUrl = res.url
+        logging.info(res.url)
+        
+        if 'LoginAgent.aspx' in agentHomeUrl:
+            logging.info('一次,登录失败,再次提交一下')
+            res = self.session.post("https://booking2.airasia.com/LoginAgent.aspx", data=self.logindata, verify=False, timeout=60)
+            agentHomeUrl = res.url
+        logging.info(agentHomeUrl)
+        logging.info(str(self.logindata))
+        htmlContent = res.text
+#         f = open('AK_Agent1.html', 'w',encoding='utf-8')
+#         f.write(res.text)
+#         f.close()
+        isReload = 'window.location.reload'
+        if isReload in htmlContent:
+            res = self.session.get(agentHomeUrl)
+            htmlContent = res.content.decode()
+        if 'ZENG' in htmlContent:
+            #登录成功
+            logging.info('AK_Agent登录成功')
+            return True
+        else:
+            #登录失败
+            logging.info('AK_Agent登录失败')
+            f = open('AK_Agent.html', 'w',encoding='utf-8')
+            f.write(res.text)
+            f.close()
+            return False
+    #查找订单
+    def lookupOrder(self):
+        res = self.session.get("https://booking2.airasia.com/BookingList.aspx")
+        page = etree.HTML(res.text)
+        queryOrderList = {
+            '__EVENTARGUMENT':'',
+            '__EVENTTARGET':'ControlGroupBookingListView$BookingListSearchInputView$LinkButtonFindBooking',
+            '__VIEWSTATE':page.xpath("//input[@id='viewState']/@value"),
+            '__VIEWSTATEGENERATOR':page.xpath("//input[@id='__VIEWSTATEGENERATOR']/@value"),
+            'ControlGroupBookingListView$BookingListSearchInputView$DropDownListTypeOfSearch':'1',
+            'ControlGroupBookingListView$BookingListSearchInputView$Search':'ForAgent',
+            'ControlGroupBookingListView$BookingListSearchInputView$TextBoxKeyword':self.orderRelation.orderNo,
+            'pageToken':''
+            }
+        logging.info(queryOrderList)
+        res = self.session.post('https://booking2.airasia.com/BookingList.aspx', data=queryOrderList, verify=False,timeout = 60)
+        logging.info('通过PRN码查找订单')
+        logging.info(str(res.status_code))
+        logging.info(res.url)
+        queryOrder = {
+            '__EVENTARGUMENT':'Edit:'+self.orderRelation.orderNo,
+            '__EVENTTARGET':'ControlGroupBookingListView$BookingListSearchInputView',
+            '__VIEWSTATE':page.xpath("//input[@id='viewState']/@value"),
+            '__VIEWSTATEGENERATOR':page.xpath("//input[@id='__VIEWSTATEGENERATOR']/@value"),
+            'ControlGroupBookingListView$BookingListSearchInputView$DropDownListTypeOfSearch':'1',
+            'ControlGroupBookingListView$BookingListSearchInputView$Search':'ForAgent',
+            'ControlGroupBookingListView$BookingListSearchInputView$TextBoxKeyword':self.orderRelation.orderNo,
+            'pageToken':''
+            }
+        logging.info(queryOrder)
+        res = self.session.post('https://booking2.airasia.com/BookingList.aspx', data=queryOrder, verify=False,timeout = 60)
+        logging.info('通过PRN码打开订单')
+        logging.info(str(res.status_code))
+        logging.info(res.url)
+        ChangeItineraryData = {
+            '__EVENTARGUMENT':'',
+            '__EVENTTARGET':'ChangeControl$LinkButtonEarnBiggies',
+            '__VIEWSTATE':page.xpath("//input[@id='viewState']/@value"),
+            '__VIEWSTATEGENERATOR':page.xpath("//input[@id='__VIEWSTATEGENERATOR']/@value"),
+            'hdRememberMeEmail':'',
+            'HiddenFieldPageBookingData':'',
+            'memberLogin_chk_RememberMe':'on',
+            'MemberLoginChangeItineraryView2$PasswordFieldPassword':'',
+            'MemberLoginChangeItineraryView2$TextBoxUserID':'',
+            'pageToken':''
+            }
+        res = self.session.post('https://booking2.airasia.com/ChangeItinerary.aspx', data=ChangeItineraryData, verify=False,timeout = 60)
+        logging.info('打开Big关联页面')
+        logging.info(str(res.status_code))
+        logging.info(res.url)
+        f = open('E://EarnBiggies.html', 'w',encoding='utf-8')
+        f.write(res.text)
+        f.close()
+        page = etree.HTML(res.text)
+        glu = page.xpath("//iframe[@id='glu']/@src")[0]
+        glu = glu.replace('http:','https:')
+        logging.info("请求Big详情子页面URL:"+glu)
+        res = self.session.get(glu)
+        logging.info('打开Big详情子页面')
+        logging.info(str(res.status_code))
+        logging.info(res.url)
+        f = open('E://PassengerBigIDLive.html', 'w',encoding='utf-8')
+        f.write(res.text)
+        f.close()
+        return res.text
+    def RelationOrder(self,relationHtml):
+        page = etree.HTML(relationHtml)
+        b = pq(relationHtml) 
+        RelationData = {
+            '__VIEWSTATE':page.xpath("//input[@id='__VIEWSTATE']/@value")[0],
+            '__VIEWSTATEGENERATOR':page.xpath("//input[@id='__VIEWSTATEGENERATOR']/@value")[0],
+            '__EVENTVALIDATION':page.xpath("//input[@id='__EVENTVALIDATION']/@value")[0],
+            'hfpnr':page.xpath("//input[@id='hfpnr']/@value")[0],
+            'hfurl':page.xpath("//input[@id='hfurl']/@value")[0],
+            '__ASYNCPOST':'true',
+            '__EVENTARGUMENT':'',
+            '__EVENTTARGET':'LinkButton1',
+            'ScriptManager1':'MainUpdatePanel|LinkButton1'
+            }
+        form2Url = page.xpath("//form[@id='form2']/@action")[0]
+        for row in page.xpath("//table[@id='GridView1']/tr"):
+            if len(row.xpath("@align")) != 0:
+               continue
+            bigname = b('span',row).text()
+            logging.info(bigname)
+            bigNo = '';
+            for passInfo in self.passengers:
+                if passInfo['firstName']+' '+passInfo['lastName'] in bigname:
+                    logging.info(passInfo['bigNo'])
+                    bigNo = passInfo['bigNo']
+                    break
+            inputName = row.xpath("./td/input/@name")
+            logging.info(inputName)
+            #判断 ['GridView1$ctl02$hfid', 'GridView1$ctl02$txbigshotid']
+            if len(bigNo) > 0:
+                #有了
+                RelationData[inputName[0]] = '1'
+                RelationData[inputName[1]] = bigNo
+            else:
+                #没有
+                RelationData[inputName[0]] = '0'
+                RelationData[inputName[1]] = ''
+        logging.info('提交URL:'+form2Url)
+        logging.info('提交参数:'+str(RelationData))
+        #https://selfservice.airasia.com/PassengerBigIDLive/
+        #does not exist
+        
+        
+        #添加设置请求头
+        self.headers['X-MicrosoftAjax'] = 'Delta=true'
+        self.headers['Host'] = 'selfservice.airasia.com'
+        self.headers['Referer'] = 'https://selfservice.airasia.com/PassengerBigIDLive/'+form2Url
+        self.headers['Cache-Control'] = 'no-cache'
+        self.headers['Content-Type'] = 'application/x-www-form-urlencoded; charset=utf-8'
+        self.session.headers.update(self.headers)
+        print(str(self.session.headers))
+        res = self.session.post('https://selfservice.airasia.com/PassengerBigIDLive/'+form2Url, data=RelationData,verify=False,timeout = 60)
+        
+        logging.info('提交成功了,检查结果如何')
+        logging.info(str(res.status_code))
+        logging.info(res.url)
+        f = open('E://PassengerBigIDLiveHo.html', 'w',encoding='utf-8')
+        f.write(res.text)
+        f.close()
+        if '0|error|500||' in res.text:
+            logging.info('关联失败')
+            return False
+        if 'does not exist' in res.text:
+            logging.info('关联失败')
+            return False
+        return True
+        

Файловите разлики са ограничени, защото са твърде много
+ 833 - 0
src/test/AKBooker_Agent.py


+ 54 - 0
src/test/RelationHtmlTest3.py

@@ -0,0 +1,54 @@
+#-*- coding:utf-8 -*-
+
+from pyquery import PyQuery as pq
+from lxml import etree
+from entity.RelationInfo import OrderRelationEntity,PassengerEntity
+
+f = open('E://PassengerBigIDLive.html',encoding='utf-8')
+queryHtml = f.read()
+b = pq(queryHtml) 
+page = etree.HTML(queryHtml)
+
+
+passengers = []
+
+passBig1 = PassengerEntity()
+passBig1.bigNo = "9999990001968964";
+passBig1.firstName = "YAJUN";
+passBig1.lastName = "LI";
+passBig1.birthday = "1989-05-16";
+
+passengers.append(passBig1)
+
+print(page.xpath("//input[@id='__VIEWSTATE']/@value")[0])
+print(page.xpath("//input[@id='__VIEWSTATEGENERATOR']/@value")[0])
+print(page.xpath("//input[@id='__EVENTVALIDATION']/@value")[0])
+print(page.xpath("//input[@id='hfpnr']/@value")[0])
+print(page.xpath("//input[@id='hfurl']/@value")[0])
+print(page.xpath("//form[@id='form2']/@action")[0])
+
+form2Url = page.xpath("//form[@id='form2']/@action")[0]
+print(form2Url)
+
+for row in page.xpath("//table[@id='GridView1']/tr"):
+    if len(row.xpath("@align")) != 0:
+       continue
+    bigname = b('span',row).text()
+    print(bigname)
+    bigNo = '';
+    for passInfo in passengers:
+        if passInfo.firstName+' '+passInfo.lastName in bigname:
+            print(passInfo.bigNo)
+            bigNo = passInfo.bigNo
+            break
+    inputName = row.xpath("./td/input/@name")
+    print(inputName)
+    #判断
+    if len(bigNo) > 0:
+        #有了
+        print("有了")
+    else:
+        #没有
+        print("没有")
+    
+    print("==================================")