Python+Selenium夷磕,實(shí)現(xiàn)12306模擬登錄

前言

本文的文字及圖片來(lái)源于網(wǎng)絡(luò),僅供學(xué)習(xí)苇侵、交流使用,不具有任何商業(yè)用途,如有問(wèn)題請(qǐng)及時(shí)聯(lián)系我們以作處理。

PS:如有需要Python學(xué)習(xí)資料的小伙伴可以加點(diǎn)擊下方鏈接自行獲取

python免費(fèi)學(xué)習(xí)資料企锌、代碼以及交流解答點(diǎn)擊即可加入

簡(jiǎn)介

這里是利用了Selenium+圖片識(shí)別驗(yàn)證榆浓,來(lái)實(shí)現(xiàn)12306的模擬登錄,中間也參考了好幾個(gè)項(xiàng)目撕攒,實(shí)現(xiàn)了這個(gè)小demo陡鹃。

中間也遇到了很多的坑烘浦,主要難點(diǎn)在于圖片識(shí)別和滑動(dòng)驗(yàn)證這兩個(gè)方面。圖片識(shí)別是利用超級(jí)鷹的服務(wù)進(jìn)行驗(yàn)證識(shí)別的萍鲸,其次一個(gè)難點(diǎn)就是在賬戶密碼和圖片識(shí)別都過(guò)了以后的滑動(dòng)驗(yàn)證闷叉,因?yàn)?2306網(wǎng)站做了反爬,利用Selenium滑動(dòng)時(shí)脊阴,會(huì)報(bào)錯(cuò)握侧,提示你一直刷新,這里也是更改了滑動(dòng)框嘿期。

技術(shù)棧

Python品擎、Selenium、圖片驗(yàn)證备徐、滑動(dòng)驗(yàn)證萄传。

思路

提前臥槽,12306網(wǎng)站的并發(fā)真的牛逼蜜猾。

在模擬登錄的時(shí)候秀菱,第一個(gè)難點(diǎn)就是圖片驗(yàn)證,這里不會(huì)底層的算法蹭睡,只能通過(guò)圖片識(shí)別平臺(tái)的api接口服務(wù)進(jìn)行解密衍菱,返回驗(yàn)證坐標(biāo)以后,通過(guò)Selenium的點(diǎn)擊動(dòng)能肩豁,進(jìn)行點(diǎn)擊脊串。

在這里提前說(shuō)明一下,網(wǎng)上有很多項(xiàng)目在實(shí)例化瀏覽器時(shí)蓖救,需要調(diào)整桌面分辨率洪规,然后最大化窗口,這樣截屏才不會(huì)出現(xiàn)截不全的情況循捺,我這邊是比較省事的斩例,直接用xpath定位到驗(yàn)證碼的png文件。直接寫(xiě)入到本地从橘,然后傳到圖片識(shí)別平臺(tái)進(jìn)行識(shí)別念赶。

里面涉及了一些Selenium的方法,我基本上都是現(xiàn)查現(xiàn)用恰力,比如按住鼠標(biāo)不放叉谜、按左鍵什么的。

具體的代碼和注解貼在下面踩萎。


from selenium import webdriver
from hashlib import md5
import requests
import time
from selenium.webdriver import ActionChains
 
#  這個(gè)類(lèi)是超級(jí)鷹平臺(tái)寫(xiě)的調(diào)用服務(wù)的接口代碼停局,也是比較容易看懂的
class Chaojiying_Client(object):
 
    def __init__(self, username, password, soft_id):
        self.username = username
        password =  password.encode('utf8')
        self.password = md5(password).hexdigest()
        self.soft_id = soft_id
        self.base_params = {
            'user': self.username,
            'pass2': self.password,
            'softid': self.soft_id,
        }
        self.headers = {
            'Connection': 'Keep-Alive',
            'User-Agent': 'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0)',
        }
 
    def PostPic(self, im, codetype):
        """
        im: 圖片字節(jié)
        codetype: 題目類(lèi)型 參考 http://www.chaojiying.com/price.html
        """
        params = {
            'codetype': codetype,
        }
        params.update(self.base_params)
        files = {'userfile': ('ccc.jpg', im)}
        r = requests.post('http://upload.chaojiying.net/Upload/Processing.php', data=params, files=files, headers=self.headers)
        return r.json()
 
    def ReportError(self, im_id):
        """
        im_id:報(bào)錯(cuò)題目的圖片ID
        """
        params = {
            'id': im_id,
        }
        params.update(self.base_params)
        r = requests.post('http://upload.chaojiying.net/Upload/ReportError.php', data=params, headers=self.headers)
        return r.json()
 
#   這里進(jìn)入模擬登錄的主程序
 
# 實(shí)例化瀏覽器,并且最大化。然后請(qǐng)求12306主網(wǎng)站董栽,我這里是從首頁(yè)請(qǐng)求的码倦,大家可以直接從登陸頁(yè)面請(qǐng)求
browser = webdriver.Chrome()
browser.maximize_window()
browser.get('http://12306.cn/')
time.sleep(5)
# 因?yàn)槭菑氖醉?yè)請(qǐng)求的,所以下面有兩個(gè)點(diǎn)擊的動(dòng)作锭碳,都是為了點(diǎn)進(jìn)登陸頁(yè)面
browser.find_element_by_xpath('//*[@id="J-header-login"]/a[1]').click()
time.sleep(0.3)
# 這里比較重要了袁稽,這里就是利用這個(gè)代碼,來(lái)更改selenium中的滑動(dòng)功能擒抛,讓網(wǎng)站不報(bào)錯(cuò)
script = 'Object.defineProperty(navigator,"webdriver",{get:()=>undefined,});'
browser.execute_script(script)
time.sleep(1)
# 這里進(jìn)入帳號(hào)登錄
browser.find_element_by_xpath('/html/body/div[2]/div[2]/ul/li[2]/a').click()
time.sleep(0.3)
#  這里直接定位驗(yàn)證碼的png文件推汽,然后保存
img = browser.find_element_by_xpath('//*[@id="J-loginImg"]')
img.screenshot('cde.png')
# 調(diào)用超級(jí)鷹的參數(shù)
chaojiying = Chaojiying_Client('用戶名', '密碼', 'ID')#  這個(gè)在超級(jí)鷹的實(shí)例代碼中有解釋
im = open('../12306/cde.png', 'rb').read()
# 注意,這里返回的是一個(gè)字典格式歧沪,所以直接取要用的key歹撒,來(lái)返回坐標(biāo)
result = chaojiying.PostPic(im, 9004)['pic_str']
print(result)
# 這里就是處理超級(jí)鷹返回坐標(biāo)的方法了
all_list = []
# 通過(guò)判斷超級(jí)鷹返回坐標(biāo)的格式進(jìn)行坐標(biāo)處理,
# 返回的坐標(biāo)有兩種形式槽畔,一種是以|隔開(kāi)的栈妆,一種是用,隔開(kāi)的胁编,對(duì)應(yīng)下面兩種處理方式
# 處理好的坐標(biāo)存入list
if '|' in result:
    list = result.split('|')
    for i in range(len(list)):
        x_y = []
        x = int(list[i].split(',')[0])
        y = int(list[i].split(',')[1])
        x_y.append(x)
        x_y.append(y)
        all_list.append(x_y)
else:
    x_y = []
    x = int(result.split(',')[0])
    y = int(result.split(',')[1])
    x_y.append(x)
    x_y.append(y)
    all_list.append(x_y)
print(all_list)
 
# 處理好的坐標(biāo)進(jìn)行循環(huán)厢钧,并帶入selenium進(jìn)行點(diǎn)擊點(diǎn)擊
for l in all_list:
    x = l[0]
    y = l[1]
    ActionChains(browser).move_to_element_with_offset(
        img, x, y).click().perform()
    time.sleep(0.5)
# 圖片點(diǎn)擊好以后,向表單內(nèi)發(fā)送賬戶密碼
browser.find_element_by_xpath('//*[@id="J-userName"]').send_keys('賬號(hào)')
browser.find_element_by_xpath('//*[@id="J-password"]').send_keys('密碼')
# 進(jìn)行點(diǎn)擊登錄按鈕
browser.find_element_by_xpath('//*[@id="J-login"]').click()
time.sleep(2)
# 下面就是滑動(dòng)模塊了
# 上面已經(jīng)更改過(guò)selenium的滑動(dòng)模塊嬉橙,所以這里就可以直接定位到按鈕的位置早直,進(jìn)行點(diǎn)擊滑動(dòng)
span = browser.find_element_by_xpath('//*[@id="nc_1_n1z"]')
action = ActionChains(browser)
# 這里是selenium的方法,按住點(diǎn)擊不放
action.click_and_hold(span)
# 下面就是滑動(dòng)了
action.drag_and_drop_by_offset(span,400,0).perform()
# 這里加了個(gè)循環(huán)市框,就是滑動(dòng)不行霞扬,一直刷新繼續(xù)滑動(dòng),直到成功
# 其實(shí)這里也只是為了保險(xiǎn)起見(jiàn)枫振,因?yàn)樯厦娓牧嘶瑒?dòng)框喻圃,基本上都會(huì)成功
while True:
    try:
        info=browser.find_element_by_xpath('//*[@id="J-slide-passcode"]/div/span').text
        print(info)
        if info=='哎呀,出錯(cuò)了粪滤,點(diǎn)擊刷新再來(lái)一次':
            #點(diǎn)擊刷新
            browser.find_element_by_xpath('//*[@id="J-slide-passcode"]/div/span/a').click()
            time.sleep(0.2)
            #重新移動(dòng)滑塊
            span = browser.find_element_by_xpath('//*[@id="nc_1_n1z"]')
            action = ActionChains(browser)
            # 點(diǎn)擊長(zhǎng)按指定的標(biāo)簽
            action.click_and_hold(span).perform()
            action.drag_and_drop_by_offset(span, 400, 0).perform()
            time.sleep(5)
    except:
        print('ok!')
        break
# 完成后斧拍,松開(kāi)鼠標(biāo)
action.release()
 
time.sleep(5)
# 退出
browser.quit()

最后想說(shuō)的是,實(shí)現(xiàn)搶票的事杖小,這個(gè)我還暫時(shí)沒(méi)想好怎么去做肆汹,平時(shí)工作比較忙,所以以后實(shí)現(xiàn)這個(gè)功能吧~

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末予权,一起剝皮案震驚了整個(gè)濱河市昂勉,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌扫腺,老刑警劉巖岗照,帶你破解...
    沈念sama閱讀 217,734評(píng)論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡攒至,警方通過(guò)查閱死者的電腦和手機(jī)煞肾,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,931評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)嗓袱,“玉大人籍救,你說(shuō)我怎么就攤上這事∏ǎ” “怎么了蝙昙?”我有些...
    開(kāi)封第一講書(shū)人閱讀 164,133評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)梧却。 經(jīng)常有香客問(wèn)我奇颠,道長(zhǎng),這世上最難降的妖魔是什么放航? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,532評(píng)論 1 293
  • 正文 為了忘掉前任烈拒,我火速辦了婚禮,結(jié)果婚禮上广鳍,老公的妹妹穿的比我還像新娘荆几。我一直安慰自己,他們只是感情好赊时,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,585評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布吨铸。 她就那樣靜靜地躺著,像睡著了一般祖秒。 火紅的嫁衣襯著肌膚如雪诞吱。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,462評(píng)論 1 302
  • 那天竭缝,我揣著相機(jī)與錄音房维,去河邊找鬼。 笑死抬纸,一個(gè)胖子當(dāng)著我的面吹牛咙俩,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播松却,決...
    沈念sama閱讀 40,262評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼暴浦,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了晓锻?” 一聲冷哼從身側(cè)響起歌焦,我...
    開(kāi)封第一講書(shū)人閱讀 39,153評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎砚哆,沒(méi)想到半個(gè)月后独撇,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,587評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,792評(píng)論 3 336
  • 正文 我和宋清朗相戀三年纷铣,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了卵史。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,919評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡搜立,死狀恐怖以躯,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情啄踊,我是刑警寧澤忧设,帶...
    沈念sama閱讀 35,635評(píng)論 5 345
  • 正文 年R本政府宣布,位于F島的核電站颠通,受9級(jí)特大地震影響址晕,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜顿锰,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,237評(píng)論 3 329
  • 文/蒙蒙 一谨垃、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧硼控,春花似錦刘陶、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,855評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)匈织。三九已至浪默,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間缀匕,已是汗流浹背纳决。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,983評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留乡小,地道東北人阔加。 一個(gè)月前我還...
    沈念sama閱讀 48,048評(píng)論 3 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像满钟,于是被迫代替她去往敵國(guó)和親胜榔。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,864評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容