Selenium自動登陸淘寶,我無心間發現了登陸漏洞!

做者:Pineapple_C
原文連接:
http://suo.im/6toKOR
注意:
本文通過原文做者受權發佈,你們能夠關注他的博客,和做者一塊兒學習。javascript

這篇文章是一個很好的學習例子,做者可以在學習過程當中,不斷髮現、不斷總結,而且可以堅持不懈。html

但願你們讀完了做者的這篇文章,可以在學習道路上 ,更有衝勁兒,更有動力。前端

1、前言

以前寫過一篇爬取淘寶商品信息的博客(原來文章的連接以下),當時仍是新手,急於完成爬取目標,乾脆手動登陸淘寶使瀏覽器保存個人信息,而後使用本地用戶配置控制瀏覽器,投機取巧地解決了登陸問題。java

原來文章連接:http://suo.im/67AJKMpython

雖然這不失爲一種方法,但這卻讓selenium的全自動變成了半自動,不配Python之美。web

那麼如何全自動登陸淘寶呢?起初我是在互聯網上找一些資源項目,直接拿來分析,但隨着淘寶的反爬機制的加強,他們的這些方法都行不通了。因而我決定,本身動手!瀏覽器

2、分析

爲了方便使用,我將整個代碼進行了封裝,文件名爲login,類名爲Login,請你們接着往下看。微信

1)相關依賴

from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait
from selenium.common.exceptions import TimeoutException
from selenium.webdriver.common.keys import Keys
from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By
from selenium import webdriver
import time

2)構造函數

def __init__(self, username, password):
     """
     初始化瀏覽器配置和登陸信息
     """

     self.url = 'https://login.taobao.com/member/login.jhtml'
     # 初始化瀏覽器選項
     options = webdriver.ChromeOptions()
     # 禁止加載圖片
     options.add_experimental_option("prefs", {"profile.managed_default_content_settings.images"2})
     # 設置爲開發者模式
     options.add_experimental_option('excludeSwitches', ['enable-automation'])
     # 加載瀏覽器選項
     self.browser = webdriver.Chrome(options=options)
     # 設置顯式等待時間40s
     self.wait = WebDriverWait(self.browser, 40)
     self.username = username  # 用戶名
     self.password = password  # 密碼

3)原始登陸,使用淘寶帳號或手機號登陸

def original(self):
    """
    直接使用淘寶帳號登陸

    :return: None
    """

    self.browser.get(url=self.url)
    try:
        input_username = self.wait.until(EC.presence_of_element_located((
            By.CSS_SELECTOR, 'div.fm-field > div.input-plain-wrap.input-wrap-loginid > input'
        )))
        input_password = self.wait.until(EC.presence_of_element_located((
            By.CSS_SELECTOR, 'div.fm-field > div.input-plain-wrap.input-wrap-password > input'
        )))
        # 等待滑塊按鈕加載
        div = self.wait.until(EC.presence_of_element_located((
            By.ID, 'nc_1__bg'
        )))
        input_username.send_keys(self.username)
        input_password.send_keys(self.password)
        # 休眠2s,等待滑塊按鈕加載
        time.sleep(2)
        # 點擊並按住滑塊
        ActionChains(self.browser).click_and_hold(div).perform()
        # 移動滑塊
        ActionChains(self.browser).move_by_offset(xoffset=300, yoffset=0).perform()
        # 等待驗證經過
        self.wait.until(EC.text_to_be_present_in_element((
            By.CSS_SELECTOR, 'div#nc_1__scale_text > span.nc-lang-cnt > b'), '驗證經過'
        ))
        # 登陸
        input_password.send_keys(Keys.ENTER)
        print('Successful !')
    except TimeoutException as e:
        print('Error:', e.args)
        self.original()

其它的結點元素的定位我就很少說了,主要說一下滑塊的定位app

利用瀏覽器定位的話,會定位到 span這個結點,但通過我模仿單擊按住,拖拽後滑塊一動不動,參數也沒有任何改變。因而我嘗試了一下它的父節點div仍是按住後拖拽,此次成功了。因此有時候不要懷疑本身的代碼,有多是其它方面的問題。編輯器

還有關於拖拽還要說明一下,淘寶的登陸驗證不是極驗驗證碼,不是拖動滑塊拼圖的操做,而是將滑塊拖到最右端。因此,至於這個最右端,只要距離夠長,且不超出界面範圍,長度隨便定!

最後補充一下,偶爾會出現這種狀況。

獲得這張圖也是很不容易啊,由於這種狀況真的是太少了。通過反覆實驗,大概是由於滑動的軌跡不是基本水平致使的,就是說朝着斜下方滑動,雖然也能到達最右端,但會給出這個錯誤。個人程序是讓它水平方向滑動300,豎直方向座標爲0。雖然是水平滑動,可是爲了提升程序的容錯率,仍是加上了一個驗證經過的等待

4)使用新浪微博帳號登陸,巧妙利用漏洞

提示:在用新浪微博登陸以前,請在淘寶上綁定你的新浪帳號。

def sina(self):
    """
    使用新浪微博帳號登陸(提早綁定新浪帳號)

    :return: None
    """

    self.browser.get(url=self.url)
    try:
        # 等待新浪登陸連接加載
        weibo_login = self.wait.until(EC.element_to_be_clickable((
            By.CSS_SELECTOR, '#login-form a.weibo-login'
        )))
        weibo_login.click()
        input_username = self.wait.until(EC.presence_of_element_located((
            By.CSS_SELECTOR, 'div.info_list > div.inp.username > input.W_input'
        )))
        input_password = self.wait.until(EC.presence_of_element_located((
            By.CSS_SELECTOR, 'div.info_list > div.inp.password > input.W_input'
        )))
        input_username.send_keys(self.username)
        input_password.send_keys(self.password)
        input_password.send_keys(Keys.ENTER)
        # 等待瀏覽器保存我方信息,網速很差能夠設置長一點
        time.sleep(5)
        # 刷新頁面
        self.browser.refresh()
        # 等待快速登陸按鈕加載
        quick_login = self.wait.until(EC.element_to_be_clickable((
            By.CSS_SELECTOR, 'div.info_list > div.btn_tip > a.W_btn_g'
        )))
        quick_login.click()
        print('login successful !')
    except TimeoutException as e:
        print('Error:', e.args)
        self.sina()

關於結點元素的定位我就很少說了,主要說一下這個漏洞

正常狀況下,輸入完信息後點擊登陸,就該進入淘寶頁面了,可是這個登陸按鈕無論怎麼點,頁面都是無動於衷。

定位一下,能夠發現:

這個按鈕的連接是javascript:void(0),假連接!!!

因爲個人前端基礎很差,不知道這啥意思。我瘋狂的在互聯網上查找如何使用selenium點擊這種連接,可依舊沒找到解決的辦法。有沒有人知道如何處理這種,請給原文做者留言!

然而就在我快放棄的時候,按了下F5刷新,奇蹟出現了

檢測到已登陸的微博帳號,快速登陸???原來雖然我沒有進入淘寶,可是瀏覽器左下角一直在顯示如:等待**相應,正在解析主機等信息。因此淘寶仍是保存了個人帳號信息,只要下次自動登陸的勾打上(默認打勾),它就會保存帳號信息。

這就是爲何上面的代碼,在輸入好信息並回車登陸後,要等待5秒,就是讓它保存個人帳號信息。

最後刷新頁面,點擊快速登陸,大功告成

3、完整代碼及使用方法

1)完整代碼

# -*- coding: utf-8 -*-
"""
@author:Pineapple

@contact:cppjavapython@foxmail.com

@time:2020/7/28 9:09

@file:login.py

@desc: login taobao .
"""


from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait
from selenium.common.exceptions import TimeoutException
from selenium.webdriver.common.keys import Keys
from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By
from selenium import webdriver
import time


class Login:
    def __init__(self, username, password):
        """
        初始化瀏覽器配置和登陸信息
        """

        self.url = 'https://login.taobao.com/member/login.jhtml'
        # 初始化瀏覽器選項
        options = webdriver.ChromeOptions()
        # 禁止加載圖片
        options.add_experimental_option("prefs", {"profile.managed_default_content_settings.images"2})
        # 設置爲開發者模式
        options.add_experimental_option('excludeSwitches', ['enable-automation'])
        # 加載瀏覽器選項
        self.browser = webdriver.Chrome(options=options)
        # 設置顯式等待時間40s
        self.wait = WebDriverWait(self.browser, 40)
        self.username = username  # 用戶名
        self.password = password  # 密碼

    def original(self):
        """
        直接使用淘寶帳號登陸

        :return: None
        """

        self.browser.get(url=self.url)
        try:
            input_username = self.wait.until(EC.presence_of_element_located((
                By.CSS_SELECTOR, 'div.fm-field > div.input-plain-wrap.input-wrap-loginid > input'
            )))
            input_password = self.wait.until(EC.presence_of_element_located((
                By.CSS_SELECTOR, 'div.fm-field > div.input-plain-wrap.input-wrap-password > input'
            )))
            # 等待滑塊按鈕加載
            div = self.wait.until(EC.presence_of_element_located((
                By.ID, 'nc_1__bg'
            )))
            input_username.send_keys(self.username)
            input_password.send_keys(self.password)
            # 休眠2s,等待滑塊按鈕加載
            time.sleep(2)
            # 點擊並按住滑塊
            ActionChains(self.browser).click_and_hold(div).perform()
            # 移動滑塊
            ActionChains(self.browser).move_by_offset(xoffset=300, yoffset=0).perform()
            # 等待驗證經過
            self.wait.until(EC.text_to_be_present_in_element((
                By.CSS_SELECTOR, 'div#nc_1__scale_text > span.nc-lang-cnt > b'), '驗證經過'
            ))
            # 登陸
            input_password.send_keys(Keys.ENTER)
            print('Successful !')
        except TimeoutException as e:
            print('Error:', e.args)
            self.original()

    def sina(self):
        """
        使用新浪微博帳號登陸(提早綁定新浪帳號)

        :return: None
        """

        self.browser.get(url=self.url)
        try:
            # 等待新浪登陸連接加載
            weibo_login = self.wait.until(EC.element_to_be_clickable((
                By.CSS_SELECTOR, '#login-form a.weibo-login'
            )))
            weibo_login.click()
            input_username = self.wait.until(EC.presence_of_element_located((
                By.CSS_SELECTOR, 'div.info_list > div.inp.username > input.W_input'
            )))
            input_password = self.wait.until(EC.presence_of_element_located((
                By.CSS_SELECTOR, 'div.info_list > div.inp.password > input.W_input'
            )))
            input_username.send_keys(self.username)
            input_password.send_keys(self.password)
            input_password.send_keys(Keys.ENTER)
            # 等待瀏覽器保存我方信息,網速很差能夠設置長一點
            time.sleep(5)
            # 刷新頁面
            self.browser.refresh()
            # 等待快速登陸按鈕加載
            quick_login = self.wait.until(EC.element_to_be_clickable((
                By.CSS_SELECTOR, 'div.info_list > div.btn_tip > a.W_btn_g'
            )))
            quick_login.click()
            print('login successful !')
        except TimeoutException as e:
            print('Error:', e.args)
            self.sina()

2)使用

在使用的時候要導入這個Login類,而後初始化這個類,最後登陸方法使用相應的函數,文件名爲login,類名爲Login。

from login import Login

username = '******'  # 帳號
password = '******.'  # 密碼
# 初始化Login類
login = Login(username, password)
# 使用淘寶帳號或手機號登陸
login.original()
# 使用新浪微博帳號登陸
# login.sina()

4、結語

本篇說的是淘寶自動登陸,其實仍是用了不少投機取巧的方法,好比:拖動滑塊的位置沒有肯定,沒有解決javascript:void(0)假連接的問題。

如果淘寶增強了反爬機制,使用極驗驗證碼等,這裏的最新版,可能也要被淘汰了,因此仍是要接着解決極驗驗證碼啊,以備後續更新!

若有錯誤,歡迎私信糾正!
技術永無止境,謝謝支持!

  

關注微信公衆號『數據分析與統計學之美』,後臺回覆"入羣" 拉你進羣哦,氣氛很好滴呀!

喜歡本文點個在看

本文分享自微信公衆號 - 數據分析與統計學之美(gh_21c25c7e71d0)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。

相關文章
相關標籤/搜索