做者: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源创计划”,欢迎正在阅读的你也加入,一块儿分享。