試了好久登入的時候總是顯示:系統忙,請重新整理,,,太折磨人了,搞了半天才想到是要求標頭部的問題.....
驗證碼還是要人工識圖..
#!/bin/env python# -*- coding=utf-8 -*-import sslimport sysimport urllib2import randomimport httplibimport jsonfrom cookielib import LWPCookieJarimport urllibimport reimport getpass reload(sys)sys.setdefaultencoding('UTF8')cookiejar = LWPCookieJar()cookiesuppor = urllib2.HTTPCookieProcessor(cookiejar)opener = urllib2.build_opener(cookiesuppor, urllib2.HTTPHandler)urllib2.install_opener(opener)ssl._create_default_https_context = ssl._create_unverified_contextcodeimg = 'https://kyfw.12306.cn/otn/passcodeNew/getPassCodeNew?module=login&rand=sjrand&%s' % random.random() baner = """################################## 12306登入指令檔,作者Mr RJL python版本:2.7,適用於linux 驗證碼輸入方式: 輸入問題對應的圖片序號,1-8; 多個以','分隔.如:1,2,3##################################"""def get(url): try: request = urllib2.Request(url=url) # req.add_header('User-Agent', 'Mozilla/5.0 (X11; Fedora; Linux x86_64; rv:52.0) Gecko/20100101 Firefox/52.0') request.add_header("Content-Type", "application/x-www-form-urlencoded; charset=utf-8") request.add_header('X-Requested-With', 'xmlHttpRequest') request.add_header('User-Agent', 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.154 Safari/537.36') request.add_header('Referer', 'https://kyfw.12306.cn/otn/login/init') request.add_header('Accept', '*/*') result = urllib2.urlopen(request).read() assert isinstance(result, object) return result except httplib.error as e: print e pass except urllib2.URLError as e: print e pass except urllib2.HTTPBasicAuthHandler, urllib2.HTTPError: print 'error' pass def Post(url, data): try: request = urllib2.Request(url=url, data=urllib.urlencode(data)) # req.add_header('User-Agent', 'Mozilla/5.0 (X11; Fedora; Linux x86_64; rv:52.0) Gecko/20100101 Firefox/52.0') # request = urllib2.Request(ajax_url, urllib.urlencode(dc)) request.add_header("Content-Type", "application/x-www-form-urlencoded; charset=utf-8") request.add_header('X-Requested-With', 'xmlHttpRequest') request.add_header('User-Agent', 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.154 Safari/537.36') request.add_header('Referer', 'https://kyfw.12306.cn/otn/login/init') request.add_header('Accept', '*/*') # request.add_header('Accept-Encoding', 'gzip, deflate') result = urllib2.urlopen(request).read() return result except httplib.error as e: return e except urllib2.URLError as e: return e except urllib2.HTTPBasicAuthHandler, urllib2.HTTPError: return 'error' def cookietp(): stoidinput("擷取Cookie") Url = "https://kyfw.12306.cn/otn/login/init" get(Url) for index, c in enumerate(cookiejar): stoidinput(c) def getImg(): stoidinput("下載驗證碼...") result = get(codeimg) try: if open('/tmp/tkcode', 'wb').write(result) : import os os.system("oeg /tmp/tkcode &") else: return False except OSError as e: print e pass def stoidinput(text): """ 正常資訊輸出 :param text: :return: """ print "\033[34m[*]\033[0m %s " % text def errorinput(text): """ 錯誤資訊輸出 :param text: :return: """ print "\033[32m[!]\033[0m %s " % text return False def codexy(): """ 擷取驗證碼 :return: str """ Ofset = raw_input("[*] 請輸入驗證碼: ") select = Ofset.split(',') global randCode post = [] offsetsX = 0 # 選擇的答案的left值,通過瀏覽器點擊8個小圖的中點得到的,這樣基本沒問題 offsetsY = 0 # 選擇的答案的top值 for ofset in select: if ofset == '1': offsetsY = 46 offsetsX = 42 elif ofset == '2': offsetsY = 46 offsetsX = 105 elif ofset == '3': offsetsY = 45 offsetsX = 184 elif ofset == '4': offsetsY = 48 offsetsX = 256 elif ofset == '5': offsetsY = 36 offsetsX = 117 elif ofset == '6': offsetsY = 112 offsetsX = 115 elif ofset == '7': offsetsY = 114 offsetsX = 181 elif ofset == '8': offsetsY = 111 offsetsX = 252 else: pass post.append(offsetsX) post.append(offsetsY) randCode = str(post).replace(']', '').replace('[', '').replace("'", '').replace(' ', '') def login(user, passwd): randurl = 'https://kyfw.12306.cn/otn/passcodeNew/checkRandCodeAnsyn' logurl = 'https://kyfw.12306.cn/otn/login/loginAysnSuggest' surl = 'https://kyfw.12306.cn/otn/login/userLogin' geturl = 'https://kyfw.12306.cn/otn/index/initMy12306' randdata = { "randCode": randCode, "rand": "sjrand" } logdata = { "loginUserDTO.user_name": user, "userDTO.password": passwd, "randCode": randCode } ldata = { "_json_att": None } fresult = json.loads(Post(randurl, randdata), encoding='utf8') checkcode = fresult['data']['msg'] if checkcode == 'FALSE': errorinput("驗證碼有誤,請重試") else: stoidinput("驗證碼通過,開始登入..") try: tresult = json.loads(Post(logurl, logdata), encoding='utf8') if tresult['data'].__len__() == 0: errorinput("登入失敗: %s" % tresult['messages'][0]) else: stoidinput("登入成功") sult = Post(surl, ldata) getUserinfo() except ValueError as e: errorinput(e) def getUserinfo(): """ 登入成功後,顯示使用者名稱 :return: """ url = 'https://kyfw.12306.cn/otn/modifyUser/initQueryUserInfo' data = dict(_json_att=None) result = Post(url, data) userinfo = result name = r'<input name="userDTO.loginUserDTO.user_name" style="display:none;" type="text" value="(\S+)" />' try: stoidinput("歡迎 %s 登入" % re.search(name, result).group(1)) except AttributeError: pass def main(): user = raw_input("[+] 使用者名稱(使用者名稱/郵箱/手機): ") passwd = getpass.getpass("[+] 密碼: ") if user == '' or passwd == '': errorinput("使用者名稱或密碼不可為空!") else: cookietp() getImg() codexy() login(user, passwd)def logout(): url = 'https://kyfw.12306.cn/otn/login/loginOut' result = get(url) if result: stoidinput("已退出") else: errorinput("退出失敗") if __name__ == "__main__": print baner main() logout()