Python+selenium+mitmproxy登录淘宝规避登陆滑动条检测

淘宝对使用selenium这种框架有检测机制,如果被发现了会导致登录强制要滑动块验证,而且不管你怎么滑动验证都会报错无法登录。淘宝加载js资源的时候会进行一些selenium特征判断,类似cdc_adaixkvasnfa89pfcZLmcfl、 window.navigator.webdriver 这种,一旦被检测到输入用户名后直接就会出现滑动条。综合网上各种教程解决淘宝登陆滑动块的思路为: 修改webdriver特征—-搭建mitmweb代理服务并注入js内容—生成并安装mitmproxy信任证书—selenium使用代理模拟登录淘宝!

本教程仅作为技术交流学习使用,请勿用于其他用途。永远记住既然你已经登录淘宝了那么你的操作在淘宝上都是留下实名记录的!

测试日期:2021-01-14
实验环境:
Mitmproxy: 5.3.0
Python:    3.7.6
OpenSSL:   OpenSSL 1.1.1h  22 Sep 2020
Platform:  Windows10
selenium: 3.141.0
Google Chrome:87.0.4280.141  使用的webdriver版本chromedriver87.0.4280.88
如果有报错提示缺少的包使用pip进行安装即可,如果使用的是firefox的Geckodriver可以不修改webdriver特征

一、修改webdriver特征

1、查看你用的谷歌浏览器的版本,在谷歌地址栏输入chrome://settings/help直接打开设置页面,我的版本号是87.0.4280.141

2、到这个网址去下载与你谷歌浏览器版本想对应的webdriver版本: http://chromedriver.storage.googleapis.com/index.html 选择的原则是尽量完全一致,如果不是完全一致至少保证前3个小数点对应的版本号一样,最后一个小数点后面的数字越大越好。如果还没有匹配的请升级浏览器或到网上找旧版本的谷歌浏览器(旧版本有个好处就是它不一定会强制验证ssl,所以可以省略一步证书安装的过程)

3、下载对应版本的驱动(windows直接下载chromedriver_win32.zip),解压后使用notepad打开chromedriver.exe文件crtl+h替换“cdc_”为“xod_”后保存放到你的python脚本同目录下。

二、安装mitmproxy进行代理

使用  pip install mitmproxy  进行安装, 系统需要首先安装 Microsoft Visual C++ V14.0以上 才行。可在https://visualstudio.microsoft.com/zh-hans/downloads/ 下载。

三、安装mitmproxy-ca.p12证书

在dos命令行下执行mitmdump命令会在当前用户文件夹下生成.mitmproxy文件夹(执行完就可关闭该dos窗口),双击mitmproxy-ca.p12进行证书安装选择受信任机构即可。

安装证书时密码留空一直下一步,证书存储时一定要选受信任的根证书颁发机构

四、为淘宝登录开启定制mitmweb代理

新建HttpProxy.py文件,内容如下:

# -*- coding:UTF-8 -*-
# HttpProxy.py
TARGET_URL = 'https://g.alicdn.com/secdev/sufei_data/3.8.1/index.js'
INJECT_TEXT = 'Object.defineProperties(navigator,{webdriver:{get:() => false}});'

def response(flow):
    if flow.request.url.startswith(TARGET_URL):
        flow.response.text = INJECT_TEXT + flow.response.text
        print('注入成功')

    if 'um.js' in flow.request.url or '115.js' in flow.request.url:
    # 屏蔽selenium检测
        flow.response.text = flow.response.text + INJECT_TEXT

新建startproxy.py文件,内容如下:

# -*- coding:UTF-8 -*-
# 第一步运行startproxy.py
# 第二步运行配置了代理的淘宝登录python脚本
from mitmproxy.tools._main import mitmweb
mitmweb(args=['-s', './HttpProxy.py', '-p', '9000', '--web-port', '9020'])

直接运行startproxy.py先启动定制的代理服务,不要关闭它!

五、python+selenium进行淘宝登录

如果你是用forefox的webdriver模拟登录,可能会发现打开的淘宝登录页全部是文字页面显示乱七八糟可能是你的Geckodriver版本与firefox浏览器版本不匹配导致的。下面会贴两段代码模拟淘宝登录的片段(改编自网络),一个是firefox版一个是chrome版

1、Firefox版,使用selenium+geckodriver.exe

# 确保代理python脚本已经开启后再执行本python脚本
from selenium import webdriver
import time
import read
import re

headers = {
    "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
    "Host": "buyertrade.taobao.com",
    "Accept-Language": "zh-CN",
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:84.0) Gecko/20100101 Firefox/84.0",
    "Connection": "keep-alive",
    "referer": "https://buyertrade.taobao.com/trade/itemlist/list_bought_items.htm"
}

option = webdriver.FirefoxOptions()

## 开启“手动设置代理”
option.set_preference('network.proxy.type', 1)
## 设置代理IP
option.set_preference('network.proxy.http', '127.0.0.1')
## 设置代理端口,注意端口是int类型,不是字符串
option.set_preference('network.proxy.http_port', 9000)
## 设置htpps协议也使用该代理
option.set_preference('network.proxy.ssl', '127.0.0.1')
option.set_preference('network.proxy.ssl_port', 9000)

option.set_preference('permissions.default.image', 2)
option.set_preference('permissions.default.stylesheet', 2)
driver = webdriver.Firefox(options=option)
driver.implicitly_wait(20)

driver.get("https://login.taobao.com")
driver.find_element_by_xpath('//*[@id="fm-login-id"]').clear()
#淘宝用户名
driver.find_element_by_xpath('//*[@id="fm-login-id"]').send_keys("ranjuan.cn")
driver.find_element_by_xpath('//*[@id="fm-login-password"]').clear()
driver.find_element_by_xpath('//*[@id="fm-login-password"]').send_keys("密码")
#old  ----time.sleep(3)

print('已经点击登录')
time.sleep(5000)

2、Chrome版,使用selenium+chromedriver.exe

# -*- coding:UTF-8 -*-
#综合改进版本

import time
from datetime import date, timedelta
from selenium import webdriver
from selenium.common.exceptions import NoSuchElementException
from selenium.webdriver import ActionChains
from selenium.webdriver.chrome.options import Options
import platform
import read
import os

TB_LOGIN_URL = 'https://login.taobao.com/member/login.jhtml'
SELECT_URL = 'https://buyertrade.taobao.com/trade/itemlist/list_bought_items.htm'

class Login:

    def __init__(self, account, password):
        self.browser = None
        self.account = account
        self.password = password

    def open(self, url):
        self.browser.get(url)
        self.browser.implicitly_wait(20)

    def start(self):
        # 1 初始化浏览器
        self.init_browser()
        # 2 打开淘宝登录页
        self.browser.get(TB_LOGIN_URL)
        time.sleep(1)
        # 3 输入用户名
        self.write_username(self.account)
        time.sleep(1.5)
        # 4 输入密码
        self.write_password(self.password)
        time.sleep(1.5)
        # 5 如果有滑块 移动滑块
        if self.lock_exist():
            self.unlock()
        # 6 点击登录按钮
        self.submit()
        # 7 登录成功,直接请求页面
        print("登录成功,跳转至目标页面进行处理")
        #这里可以写一些登录后需要python处理的逻辑
        #self.browser.get('https://buyertrade.taobao.com/trade/itemlist/list_bought_items.htm')
        print("over")
        time.sleep(5000)


    def switch_to_password_mode(self):
        """
        切换到密码模式
        :return:
        """
        if self.browser.find_element_by_id('J_QRCodeLogin').is_displayed():
            self.browser.find_element_by_id('J_Quick2Static').click()

    def write_username(self, username):
        """
        输入账号
        :param username:
        :return:
        """
        try:
            username_input_element = self.browser.find_element_by_id('fm-login-id')
        except:
            username_input_element = self.browser.find_element_by_id('TPL_username_1')

        username_input_element.clear()
        username_input_element.send_keys(username)

    def write_password(self, password):
        """
        输入密码
        :param password:
        :return:
        """

        try:
            password_input_element = self.browser.find_element_by_id("fm-login-password")
        except:
            password_input_element = self.browser.find_element_by_id('TPL_password_1')

        #

        password_input_element.clear()
        password_input_element.send_keys(password)

    def lock_exist(self):
        """
        判断是否存在滑动验证
        :return:
        """
        return self.is_element_exist('#nc_1_wrapper') and self.browser.find_element_by_id(
            'nc_1_wrapper').is_displayed()

    def unlock(self):
        """
        执行滑动解锁
        :return:
        """
        if self.is_element_exist("#nocaptcha > div > span > a"):
            self.browser.find_element_by_css_selector("#nocaptcha > div > span > a").click()

        bar_element = self.browser.find_element_by_id('nc_1_n1z')
        ActionChains(self.browser).drag_and_drop_by_offset(bar_element, 258, 0).perform()
        if self.is_element_exist("#nocaptcha > div > span > a"):
            self.unlock()
        time.sleep(0.5)

    def submit(self):
        """
        提交登录
        :return:
        """
        try:
            self.browser.find_element_by_css_selector("#login-form > div.fm-btn > button").click()
        except:
            self.browser.find_element_by_id('J_SubmitStatic').click()

        time.sleep(0.5)
        if self.is_element_exist("#J_Message"):
            self.write_password(self.password)
            self.submit()
            time.sleep(5)

    def navigate_to_target_page(self):
        pass

    # def init_date(self):
    #     date_offset = 0
    #     self.today_date = (date.today() + timedelta(days=-date_offset)).strftime("%Y-%m-%d")
    #     self.yesterday_date = (date.today() + timedelta(days=-date_offset-1)).strftime("%Y-%m-%d")

    def init_browser(self):
        self.downloadPath = os.getcwd()
        CHROME_DRIVER = os.path.abspath(os.path.dirname(os.getcwd())) + os.sep + 'chromedriver' + os.sep
        if platform.system() == 'Windows':
            CHROME_DRIVER = os.getcwd() + os.sep + 'chromedriver87.0.4280.88.exe'
        if platform.system() == 'Linux':
            CHROME_DRIVER = os.getcwd() + os.sep + 'chromedriver'
        """
        初始化selenium浏览器
        :return:
        """
        
        headers = {
    "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
    "Host": "buyertrade.taobao.com",
    "Accept-Language": "zh-CN",
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:84.0) Gecko/20100101 Firefox/84.0",
    "Connection": "keep-alive",
    "referer": "https://buyertrade.taobao.com/trade/itemlist/list_bought_items.htm"
}
        
        
        
        
        options = Options()
        # options.add_argument("--headless")
        # prefs = {"profile.managed_default_content_settings.images": 2}
        prefs = {"profile.managed_default_content_settings.images": 2, 'download.default_directory': self.downloadPath}
        # 1是加载图片,2是不加载图片
        options.add_experimental_option("prefs", prefs)
        options.add_argument('--proxy-server=http://127.0.0.1:9000')
        options.add_argument('disable-infobars')
        options.add_argument('--no-sandbox')
        self.browser = webdriver.Chrome(executable_path=CHROME_DRIVER, options=options)
        self.browser.implicitly_wait(3)
        self.browser.maximize_window()

    def is_element_exist(self, selector):
        """
        检查是否存在指定元素
        :param selector:
        :return:
        """
        try:
            self.browser.find_element_by_css_selector(selector)
            return True
        except NoSuchElementException:
            return False

account = 'ranjuan.cn'
# 输入你的账号名
password = '密码'
# 输入你密码
Login(account,password).start()

基于互联网精神,在注明出处的前提下本站文章可自由转载!

本文链接:https://ranjuan.cn/python-selenium-mitmproxy-login-taobao/

赞赏

微信赞赏支付宝赞赏

weixin-nfc-mifareclassic
计算机系统之映像劫持
axure9-bullet-screen