12-基於selenium實現12306模擬登錄,及京東登錄滑動缺口驗證模擬登錄


流程分析:

  • 使用selenium打開登錄頁面
  • 對當前selenium打開的這張頁面進行截圖
  • 對當前圖片的局部區域(驗證碼圖片區域)進行截圖
    • 這樣驗證碼圖片和模擬登錄進行所顯示的圖片一一對應(如果我們對圖片發起請求每次請求都不一樣無法准確定位及點擊)
  • 使用超級鷹識別驗證碼圖片(坐標)

在這里插入圖片描述
在這里插入圖片描述

對當前selenium打開的這張頁面進行截圖

# -*- coding: utf-8 -*-
from selenium import webdriver
import time
from PIL import Image
from Chaojiying_Python import chaojiying
from selenium.webdriver import ActionChains


bro = webdriver.Chrome()
url = "https://kyfw.12306.cn/otn/resources/login.html"
bro.get(url)
bro.implicitly_wait(5) #靜默等待最大5秒,保證頁面加載完畢
time.sleep(1)
bro.find_element_by_xpath("/html/body/div[2]/div[2]/ul/li[2]/a").click()
bro.save_screenshot('aa.png')# save_screenshot 將當前頁面進行截圖保存

# 確定驗證碼圖片對應的左上角和右下角坐標(裁剪的區域就確定了)
code_img_ele = bro.find_element_by_xpath('//*[@id="J-loginImg"]')
location = code_img_ele.location # 驗證碼圖片左上角的坐標 x,y
print("location:",location)
size = code_img_ele.size # 驗證碼標簽對應的長和寬
print("size",size)

在這里插入圖片描述

定位驗證碼圖片左上角及右下角得坐標

# -*- coding: utf-8 -*-
from selenium import webdriver
import time
from PIL import Image
from Chaojiying_Python import chaojiying
from selenium.webdriver import ActionChains


bro = webdriver.Chrome()
url = "https://kyfw.12306.cn/otn/resources/login.html"
bro.get(url)
bro.implicitly_wait(5) #靜默等待最大5秒,保證頁面加載完畢
time.sleep(1)
bro.find_element_by_xpath("/html/body/div[2]/div[2]/ul/li[2]/a").click()
bro.save_screenshot('aa.png')# save_screenshot 將當前頁面進行截圖保存

# 確定驗證碼圖片對應的左上角和右下角坐標(裁剪的區域就確定了)
code_img_ele = bro.find_element_by_xpath('//*[@id="J-loginImg"]')
location = code_img_ele.location # 驗證碼圖片左上角的坐標 x,y
print("location:",location)
size = code_img_ele.size # 驗證碼標簽對應的長和寬
print("size",size)
# # 左下角和右下角坐標
rangle = (int(location["x"]),int(location["y"]),int(location["x"] + size["width"]),int(location["y"] + size["height"]))
print(rangle)

在這里插入圖片描述

根據坐標區域進行裁剪

# -*- coding: utf-8 -*-
from selenium import webdriver
import time
from PIL import Image
from Chaojiying_Python import chaojiying
from selenium.webdriver import ActionChains


bro = webdriver.Chrome()
url = "https://kyfw.12306.cn/otn/resources/login.html"
bro.get(url)
bro.implicitly_wait(5) #靜默等待最大5秒,保證頁面加載完畢
time.sleep(1)
bro.find_element_by_xpath("/html/body/div[2]/div[2]/ul/li[2]/a").click()
bro.save_screenshot('aa.png')# save_screenshot 將當前頁面進行截圖保存

# 確定驗證碼圖片對應的左上角和右下角坐標(裁剪的區域就確定了)
code_img_ele = bro.find_element_by_xpath('//*[@id="J-loginImg"]')
location = code_img_ele.location # 驗證碼圖片左上角的坐標 x,y
print("location:",location)
size = code_img_ele.size # 驗證碼標簽對應的長和寬
print("size",size)
# # 左下角和右下角坐標
rangle = (int(location["x"]),int(location["y"]),int(location["x"] + size["width"]),int(location["y"] + size["height"]))
print(rangle)
# 至此驗證碼圖片的區域我們就確定下來了
i = Image.open("aa.png")
code_img_name = 'C:/Users/gpc/Desktop/python/Chaojiying_Python/12306.png'
# crop 根據指定區域進行圖片裁剪
frame = i.crop(rangle)
frame.save(code_img_name)# 保存

在這里插入圖片描述

將驗證碼圖片提交給超級鷹

超級鷹的使用方法可參考: 07-爬蟲驗證碼破解實戰

# -*- coding: utf-8 -*-
from selenium import webdriver
import time
from PIL import Image
from Chaojiying_Python import chaojiying
from selenium.webdriver import ActionChains


bro = webdriver.Chrome()
url = "https://kyfw.12306.cn/otn/resources/login.html"
bro.get(url)
bro.implicitly_wait(5) #靜默等待最大5秒,保證頁面加載完畢
bro.maximize_window()  # 窗口最大化
time.sleep(1)
bro.find_element_by_xpath("/html/body/div[2]/div[2]/ul/li[2]/a").click()
bro.save_screenshot('aa.png')# save_screenshot 將當前頁面進行截圖保存

# 確定驗證碼圖片對應的左上角和右下角坐標(裁剪的區域就確定了)
code_img_ele = bro.find_element_by_xpath('//*[@id="J-loginImg"]')
location = code_img_ele.location # 驗證碼圖片左上角的坐標 x,y
print("location:",location)
size = code_img_ele.size # 驗證碼標簽對應的長和寬
print("size",size)
# # 左下角和右下角坐標
rangle = (int(location["x"]),int(location["y"]),int(location["x"] + size["width"]),int(location["y"] + size["height"]))
print(rangle)
# 至此驗證碼圖片的區域我們就確定下來了
i = Image.open("aa.png")
code_img_name = 'C:/Users/gpc/Desktop/python/Chaojiying_Python/12306.png'
# crop 根據指定區域進行圖片裁剪
frame = i.crop(rangle)
frame.save(code_img_name)# 保存

# 將驗證碼圖片提交給超級鷹進行識別
yanzhengma = chaojiying.Chaojiying_Client.tranformImgCode()
print(yanzhengma)

在這里插入圖片描述

點擊驗證碼並登錄賬號

# -*- coding: utf-8 -*-
from selenium import webdriver
import time
from PIL import Image
from Chaojiying_Python import chaojiying
from selenium.webdriver import ActionChains


bro = webdriver.Chrome()
url = "https://kyfw.12306.cn/otn/resources/login.html"
bro.get(url)
bro.implicitly_wait(5) #靜默等待最大5秒,保證頁面加載完畢
bro.maximize_window()  # 窗口最大化
time.sleep(1)
bro.find_element_by_xpath("/html/body/div[2]/div[2]/ul/li[2]/a").click()
bro.save_screenshot('aa.png')# save_screenshot 將當前頁面進行截圖保存

# 確定驗證碼圖片對應的左上角和右下角坐標(裁剪的區域就確定了)
code_img_ele = bro.find_element_by_xpath('//*[@id="J-loginImg"]')
location = code_img_ele.location # 驗證碼圖片左上角的坐標 x,y
print("驗證碼圖片左上角坐標:",location)
size = code_img_ele.size # 驗證碼標簽對應的高和寬
print("驗證碼圖片的高和寬:",size)
# # 左上角和右下角坐標
rangle = (int(location["x"]),int(location["y"]),int(location["x"] + size["width"]),int(location["y"] + size["height"]))
print("驗證碼圖片左上角和右下角坐標:",rangle)
# 至此驗證碼圖片的區域我們就確定下來了
i = Image.open("aa.png")
code_img_name = 'C:/Users/gpc/Desktop/python/Chaojiying_Python/12306.png'
# crop 根據指定區域進行圖片裁剪
frame = i.crop(rangle)
frame.save(code_img_name)# 保存

# 將驗證碼圖片提交給超級鷹進行識別
yanzhengma = chaojiying.Chaojiying_Client.tranformImgCode()
print("超級鷹識別出來的待點擊的坐標值:",yanzhengma)

all_list = [] # 存儲即將被點擊的點坐標 [[x1,y1],[x2,y2]]
if "|" in yanzhengma:
    list_1 = yanzhengma.split("|")
    count_1 = len(list_1)
    for i in range(count_1):
        xy_list = []
        x = int(list_1[i].split(",")[0])
        y = int(list_1[i].split(",")[1])
        xy_list.append(x)
        xy_list.append(y)
        all_list.append(xy_list)
else:
    x = int(yanzhengma.split(",")[0])
    y = int(yanzhengma.split(",")[1])
    xy_list = []
    xy_list.append(x)
    xy_list.append(y)
    all_list.append(xy_list)

print(all_list)

# 遍歷位置列表,使用動作鏈對每一個列表元素對應的x,y指定的位置進行點擊操作
for l in all_list:
    x = l[0]
    y = l[1]
    ActionChains(bro).move_to_element_with_offset(code_img_ele,x,y).click().perform()#動作鏈
    time.sleep(0.5)

# 輸入用戶名密碼
bro.find_element_by_id('J-userName').send_keys('18398141111')
time.sleep(1)
bro.find_element_by_id('J-password').send_keys('11111')
time.sleep(1)
bro.find_element_by_id('J-login').click()

#bro.quit()#退出

在這里插入圖片描述

在這里插入圖片描述

滑動模塊破解

加入動作鏈滑動代碼如下

# -*- coding: utf-8 -*-
from selenium import webdriver
import time
from PIL import Image
from Chaojiying_Python import chaojiying
from selenium.webdriver import ActionChains


bro = webdriver.Chrome()
url = "https://kyfw.12306.cn/otn/resources/login.html"
bro.get(url)
bro.implicitly_wait(5) #靜默等待最大5秒,保證頁面加載完畢
bro.maximize_window()  # 窗口最大化
time.sleep(1)
bro.find_element_by_xpath("/html/body/div[2]/div[2]/ul/li[2]/a").click()
bro.save_screenshot('aa.png')# save_screenshot 將當前頁面進行截圖保存

# 確定驗證碼圖片對應的左上角和右下角坐標(裁剪的區域就確定了)
code_img_ele = bro.find_element_by_xpath('//*[@id="J-loginImg"]')
location = code_img_ele.location # 驗證碼圖片左上角的坐標 x,y
print("驗證碼圖片左上角坐標:",location)
size = code_img_ele.size # 驗證碼標簽對應的高和寬
print("驗證碼圖片的高和寬:",size)
# # 左上角和右下角坐標
rangle = (int(location["x"]),int(location["y"]),int(location["x"] + size["width"]),int(location["y"] + size["height"]))
print("驗證碼圖片左上角和右下角坐標:",rangle)
# 至此驗證碼圖片的區域我們就確定下來了
i = Image.open("aa.png")
code_img_name = 'C:/Users/gpc/Desktop/python/Chaojiying_Python/12306.png'
# crop 根據指定區域進行圖片裁剪
frame = i.crop(rangle)
frame.save(code_img_name)# 保存

# 將驗證碼圖片提交給超級鷹進行識別
yanzhengma = chaojiying.Chaojiying_Client.tranformImgCode()
print("超級鷹識別出來的待點擊的坐標值:",yanzhengma)

all_list = [] # 存儲即將被點擊的點坐標 [[x1,y1],[x2,y2]]
if "|" in yanzhengma:
    list_1 = yanzhengma.split("|")
    count_1 = len(list_1)
    for i in range(count_1):
        xy_list = []
        x = int(list_1[i].split(",")[0])
        y = int(list_1[i].split(",")[1])
        xy_list.append(x)
        xy_list.append(y)
        all_list.append(xy_list)
else:
    x = int(yanzhengma.split(",")[0])
    y = int(yanzhengma.split(",")[1])
    xy_list = []
    xy_list.append(x)
    xy_list.append(y)
    all_list.append(xy_list)

print("被點擊的坐標位置:",all_list)

# 遍歷位置列表,使用動作鏈對每一個列表元素對應的x,y指定的位置進行點擊操作
for l in all_list:
    x = l[0]
    y = l[1]
    ActionChains(bro).move_to_element_with_offset(code_img_ele,x,y).click().perform()#動作鏈
    time.sleep(0.5)

# 輸入用戶名密碼
bro.find_element_by_id('J-userName').send_keys('18398141111')
time.sleep(1)
bro.find_element_by_id('J-password').send_keys('11111')
time.sleep(1)
bro.find_element_by_id('J-login').click()

# 加入動作鏈
div_tag = bro.find_element_by_xpath('//*[@id="nc_1_wrapper"]')

# 對div_tag進行滑動操作
action = ActionChains(bro) #實例化一個動作對象
action.click_and_hold(div_tag) # 點擊且長按不放

for i in range(6):
    # perform 讓動作鏈立即執行
    action.move_by_offset(20,0).perform() #偏移x20像素,y0像素
    time.sleep(0.1)
action.release()




#bro.quit()#退出

結果如下:
在這里插入圖片描述

京東缺口滑動驗證碼

# -*- coding: utf-8 -*-
from collections import Counter
from PIL import Image
from selenium import webdriver
import time
from selenium.webdriver.common.action_chains import ActionChains

class JDlogin():
    def __init__(self):#定義函數,鏈接登錄頁面
        self.driver = driver = webdriver.Chrome()#啟動調試工具
        self.driver.get('https://passport.jd.com/new/login.aspx')#獲取JD登陸頁面
        self.driver.implicitly_wait(5)  # 靜默等待最大5秒,保證頁面加載完畢
        time.sleep(2)


    def get_picture(self):#獲取圖片
    #通過xpath尋找按鍵點擊“賬戶登陸”
        self.driver.find_element_by_xpath('.//div[@class="login-tab login-tab-r"]/a').click()
        time.sleep(1)
        #定位賬號輸入框
        self.driver.find_element_by_xpath('.//input[@id="loginname"]').send_keys('賬號')
        time.sleep(1)
        #定位密碼輸入框
        self.driver.find_element_by_xpath('.//input[@id="nloginpwd"]').send_keys('密碼')
        time.sleep(1)
        #定位登陸按鈕,並點擊,此時會展示出驗證碼圖片
        self.driver.find_element_by_xpath('.//div[@class="login-btn"]/a').click()
        time.sleep(1)
        #通過修改JS隱藏滑塊並截屏獲取驗證碼圖片,保存至當前目錄,名為slice.png(雙層圖也是這么干,不過ClassName與xpath需要改動)
        js = 'document.getElementsByClassName("JDJRV-smallimg")[0].style.display="none"'
        self.driver.execute_script(js)
        slice_path = './slice.png'
        self.driver.find_element_by_xpath('.//div[@class="JDJRV-bigimg"]').screenshot(slice_path)
        time.sleep(1)
        #停止1秒后恢復JS改動,回到頁面最初狀態(雙層圖亦然)
        js = 'document.getElementsByClassName("JDJRV-smallimg")[0].style.display="block"'
        self.driver.execute_script(js)

#將獲得的驗證碼圖片進行處理(灰度化、二值化、降噪)
#雙層圖可以直接進行兩張圖片的比較,而單層圖則需要處理之后進行自身比較,本案例為單層圖事例

    def shape(self, w, h, image):  # 二值化,將所有的點位,全部換成0或255
        tem = 0
        for x in range(w):
            for y in range(h):
                tem += image.getpixel((x, y))
        pixel_ave = tem / w / h * 0.7
        for x in range(w):
            for y in range(h):
                p = image.getpixel((x, y))
                if p < pixel_ave:
                    image.putpixel((x, y), 0)
                else:
                    image.putpixel((x, y), 255)
        return image

    def reducenoise(self, image):#降噪處理
        w, h = image.size
        for x in range(0, 40):  # 處理最左邊
            for y in range(h):
                image2 = image.putpixel((x, y), 255)
        return image

    def make_picture(self):  # 處理圖片,灰度化與二值化、降噪
        im = Image.open('slice.png')
        im2 = im.convert("L")
        w, h = im2.size
        im3 = self.shape(w, h, im2)
        im4 = self.reducenoise(im3)
        return im3

#計算驗證圖片左邊邊界到缺口左邊邊界的距離(即滑塊拖動距離)

    def get_juli(self, image):  # 計算距離
        w, h = image.size
        ls = []
        for i in range(31, w - 31):#圖片最左邊放置滑塊,缺口坐標x不可能小於31
            for j in range(10, h):
                if image.getpixel((i, j)) < 100:
                    count = 0
                    for k in range(i, i + 31):
                        if image.getpixel((k, j)) < 100:
                            count += 1
                        else:
                            break
                    if count > 27: ls.append(i)

        return Counter(ls).most_common(1)[0][0]

#設計拖動軌跡
    def get_track(self, distance):  # 設計拖動軌跡
        ls = [1]
        while 1:
            i = ls[-1] * 2
            ls.append(i)
            if sum(ls) > distance * 0.7:
                break

        ls.append(int(distance - sum(ls)))

        return ls
    
#通過selenium執行拖動滑塊的指令,實現驗證登陸
    def drog_btn(self, track):  # 拖動滑塊
    #定位滑塊
        ele = self.driver.find_element_by_xpath('.//div[@class="JDJRV-slide-inner JDJRV-slide-btn"]')
        #設計拖動動作鏈(點擊且不放)
        ActionChains(self.driver).click_and_hold(ele).perform()
        #根據設計的軌跡,實現滑塊拖動
        for i in track:
            ActionChains(self.driver).move_by_offset(i, 0).perform()#鼠標從當前位置移動到某個坐標
    #睡眠0.25秒,偽裝成人的等一下松開鼠標的操作
            time.sleep(0.25)
        #釋放滑塊,類似於松開鼠標
        ActionChains(self.driver).release().perform()
        time.sleep(2)





    def check(self):#再次嘗試
        self.get_picture()
        image = self.make_picture()
        distance = self.get_juli(image)
        track = self.get_track(distance)
        self.drog_btn(track)


if __name__ == '__main__':
    login = JDlogin()
    login.get_picture()
    image = login.make_picture()
    distance = login.get_juli(image)
    track = login.get_track(distance)
    login.drog_btn(track)
    time_int = 0
    while time_int < 5:
        input("是否需要再次嘗試")
        login.driver.refresh()
        login.check()
        time_int += 1

ActionChains動作鏈方法列表

click(on_element=None) ——單擊鼠標左鍵
click_and_hold(on_element=None) ——點擊鼠標左鍵,不松開
context_click(on_element=None) ——點擊鼠標右鍵
double_click(on_element=None) ——雙擊鼠標左鍵
drag_and_drop(source, target) ——拖拽到某個元素然后松開
drag_and_drop_by_offset(source, xoffset, yoffset) ——拖拽到某個坐標然后松開
key_down(value, element=None) ——按下某個鍵盤上的鍵
key_up(value, element=None) ——松開某個鍵
move_by_offset(xoffset, yoffset) ——鼠標從當前位置移動到某個坐標
move_to_element(to_element) ——鼠標移動到某個元素
move_to_element_with_offset(to_element, xoffset, yoffset) ——移動到距某個元素(左上角坐標)多少距離的位置
perform() ——執行鏈中的所有動作
release(on_element=None) ——在某個元素位置松開鼠標左鍵
send_keys(*keys_to_send) ——發送某個鍵到當前焦點的元素
send_keys_to_element(element, *keys_to_send) ——發送某個鍵到指定元素


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM