Python selenium淘寶自動登錄(最新版),無意間發現淘寶登錄漏洞?


一、前言

重大跟新https://blog.csdn.net/pineapple_C/article/details/108181761post請求模擬登錄淘寶並爬取商品列表信息

之前寫過一篇爬取淘寶商品信息的博客----<<傳送門,當時還是新手,急於完成爬取目標,干脆手動登錄淘寶使瀏覽器保存我的信息,然后使用本地用戶配置控制瀏覽器,投機取巧地解決了登錄問題。雖然這不失為一種方法,但這卻讓selenium的“全自動”變成了“半自動”,不配Python之美。

那么如何“全自動”登錄淘寶呢?起初我是在互聯網上找一些資源項目,直接拿來分析,但隨着淘寶的反爬機制的增強,他們的這些方法都行不通了。於是我決定,自己動手!

二、分析

為了方便使用,把代碼進行了封裝)文件名為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)原始登錄,使用淘寶賬號或手機號登錄

2020-8-1,出現的新問題:經過多次、不同電腦的嘗試,滑塊滑動后始終報錯!手動也報錯!尚未解決!!!求答案!

    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()

其它的結點元素的定位我就不多說了,主要說一下滑塊的定位
在這里插入圖片描述

利用瀏覽器定位的話,會定位到 span 這個結點,但經過我模仿單擊按住,拖拽后滑塊一動不動,參數也沒有任何改變。於是我嘗試了一下它的父節點 div 還是按住后拖拽,這次成功了。所以有時候不要懷疑自己的代碼,有可能是其它方面的問題。

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

最后補充一下,偶爾會出現這種情況
在這里插入圖片描述得到這張圖也是很不容易啊,因為這種情況真的是太少了。經過反復實驗,大概是因為滑動的軌跡不是基本水平導致的,就是說朝着斜下方滑動,雖然也能到達最右端,但會給出這個錯誤。我的程序是讓它水平方向滑動300,豎直方向坐標為0。雖然是水平滑動,但是為了提高程序的容錯率,還是加上了一個驗證通過的等待。

(3)使用新浪微博賬號登錄,巧妙利用漏洞

提示:在用新浪微博登錄之前,請在淘寶上綁定你的新浪賬號

    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秒,就是讓它保存我的賬號信息。

最后刷新頁面,點擊快速登錄,大功告成!

三、完整代碼及使用方法

完整代碼

# -*- 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()

如何使用

在使用的時候要導入這個Login類,然后初始化這個類,最后登錄方法使用相應的函數,比如:
文件名為login,類名為Login

from login import Login

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

小插曲:

如果你用的是PyCarm,可能會出現如下問題:

在這里插入圖片描述雖然不妨礙運行,但是身為強迫症患者,怎么可能容忍波浪線的存在!

解決方法:右擊文件夾,點擊Sources Root,將文件夾設置為根目錄。
在這里插入圖片描述

如果用的是VS code,在導入的時候並不會出現上面的問題,但是你會發現突然多了一個文件夾,並且里面還有一個.pyc文件:

在這里插入圖片描述不要慌,有這個才是正常的現象!

文件名:login.cpython-38.pyc。login代表導入的文件名,cpython指的是我們使用的python解釋器,38代表python版本,pyc是python字節碼文件的后綴。

python文件在運行的時候,Python解釋器將源碼轉換為字節碼,然后再由解釋器來執行這些字節碼。

在導入模塊的時候,python將該模塊的字節碼文件保存在當前文件夾下,后續再次運行直接,若模塊沒有被改動,就直接執行字節碼文件,這樣就縮短了程序運行的時間。

四、結語

本篇說的是淘寶自動登錄,其實還是用了很多投機取巧的方法,比如:拖動滑塊的位置沒有確定,沒有解決javascript:void(0)假鏈接的問題。若是淘寶加強了反爬機制,使用極驗驗證碼等,這個標題里的“最新版”,可能也要被淘汰了,所以還是要接着解決極驗驗證碼啊,以備后續跟新!


免責聲明!

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



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