python 网页登录selenium_Selenium网页自动登录项目(基于Python从0到1)

Selenium是一个自动化测试工具,利用它我们可以驱动浏览器执行特定的动作,如点击、下拉等操作。

本文讲述的是通过自动化的方式登陆某一网站,其中包含Selenium+python自动化项目环境如何部署, 获取图形验证码登录,元素获取方法,项目中遇到的问题,看完你会发现原来Selenium自动化轻松入门,是多么的简单,Selenium+python也可以用于爬虫。

本文将从环境部署到项目开发一步步讲解,包括这个过程所可能遇到的一些问题,都会一一解答,有不会的问题可以在下方评论留言一起思考解决。

一.环境部署

环境部署包括mac和linux

1.安装Selenium

pip3 install selenium

这里推荐大家使用Anaconda管理python包及环境,Anaconda是一个方便的python包管理和环境管理软件,一般用来配置不同的项目环境。如果你的电脑只能安装一个环境,而两个项目却用着不同的环境,那么你可以使用Anaconda创建多个互不干扰的环境,分别运行不同版本的软件包,以达到兼容的目的。

Anaconda通过管理工具包、开发环境、Python版本,大大简化了你的工作流程。不仅可以方便地安装、更新、卸载工具包,而且安装时能自动安装相应的依赖包,同时还能使用不同的虚拟环境隔离不同要求的项目。

Anaconda的安装流程及使用

2.安装ChromeDriver

2.1.查看浏览器版本

2.2.在浏览器的帮助/关于Google Chrome 查看浏览器版本

2.3.下载相应的ChromeDriver(两种方法)

方法一 :

打开ChromeDriver官方网站,根据上面的浏览器版本,下载相应版本的ChromeDriver

将解压好的文件放入/usr/local/bin目录中,由于mac的很多目录都是隐藏的,所以我们按快捷键command+shift+g,在弹出的窗口输入/usr/local/bin,就可以打开这个目录,接着将解压好的驱动放入此目录即可。

进行测试(在终端输入: chromedriver --version,可以查看到版本)

方法二 :

1.安装brew及使用可能遇到的问题

2.下载chromedriver

通过命令brew cask install chromedriver去下载

3.测试

在终端输入: chromedriver --version,可以查看到版本

3.安装识别验证码的包

1.用homebrew 在电脑上安装tesseract库

brew install tesseract

2.用pip安装支持python的tesseract

pip install pytesseract

如果是识别中文

去往https://github.com/tesseract-ocr/tessdata下载中文数据集chi_sim.traineddata,把它放到这目录下:

/usr/local/Cellar/tesseract/3.05.01/share/tessdata

3.安装容易遇到的问题:

提示brew update,代表homebrew需要更新

提示must be writable!或者Permission denied之类问题,试试前面加sudo

提示Please check the permissions and owner of that directory,说明权限有问题,那么使用sudo chown root 文件路径命令获得临时root权限

提示Xcode alone is not sufficient on Sierra,使用xcode-select --install

二.实现逻辑

开始想的逻辑是,获取到验证码的地址,然后爬取下来并请求,下载验证码图片并识别再填上去,发现这样行不通,每次请求获得的验证码图片不一致,这得从会话角度去解决问题。这里我换了种思维更简单的去解决这个问题,通过截图的方式把页面上的验证码截图下来保存为图片并识别出文字。

1. 实现中所遇到的问题

chromedriver的截图只能截取当前页面的图片,不能得到整个页面的图片,这样就不能通过定位验证码图片的位置去截取验证码图片,对于页面有滑动的只能手动调试位置。

处理验证码失败的提示框

当从a页面跳转到b网页,然后获取b页面的某个元素时,容易出错。因为代码执行速度比网页加载速度快,通常会出现无法找到该元素的错误。遇到无法找到页面元素的情况,要考虑是否是代码加载过快的原因,处理方法:在获取元素前➕time.sleep(2)

快速获取元素路径的方式:网页->检查->选中对应标签->右键选择copy->copy xpath

2. 用到的一些方法

2.1 处理Windows弹出框(三种情况)

使用 driver.switch_to.alert 切换到Windows弹出框

Alert类提供了一系列操作方法:

accept() 确定

dismiss() 取消

text() 获取弹出框里面的内容

send_keys(keysToSend) 输入字符串

A.定位alert弹出框

#点击页面元素,触发alert弹出框

driver.find_element_by_xpath('//*[@id="alert"]').click()

time.sleep(3)

#等待alert弹出框可见

WebDriverWait(driver,20).until(EC.alert_is_present())

#从html页面切换到alert弹框

alert = driver.switch_to.alert

#获取alert的文本内容

print(alert.text)

#接受--选择“确定”

alert.accept()

B.定位confirm弹出框

driver.find_element_by_xpath('//*[@id="confirm"]').click()

time.sleep(3)

WebDriverWait(driver,20).until(EC.alert_is_present())

alert =driver.switch_to.alert

print(alert.text)

# 接受--选择“取消”

alert.dismiss()

C.定位prompt弹出框

driver.find_element_by_id("prompt").click()

time.sleep(3)

WebDriverWait(driver,20).until(EC.alert_is_present())

alert =driver.switch_to.alert

alert.send_keys("jaja")

time.sleep(5)

print(alert.text)

# alert.dismiss()

alert.accept()

2.2 python+selenium调用js方法

from selenium import webdriver

js = '''var str="联想词:%s===>车系:%s";window.alert(str);''' % (alias, name)

driver.execute_script(js)

execute_script(js)和execute_async_script(js)分别是是同步和异步方法,前者会等待js代码执行完毕后主线程执行,后者它不会阻塞主线程执行。

execute_script(js) 方法如果有返回值,有以下几种情况:

* 如果返回一个页面元素(document element), 这个方法就会返回一个WebElement

* 如果返回浮点数字,这个方法就返回一个double类型的数字

* 返回非浮点数字,方法返回Long类型数字

* 返回boolean类型,方法返回Boolean类型

* 如果返回一个数组,方法会返回一个List

* 其他情况,返回一个字符串

* 如果没有返回值,此方法就会返回null

2.3selenium+python的常用方法

1.创建webdriver对象

browser=webdriver.Chrome()

2.打开百度页面

browser.get('https://www.baidu.com')

3.获取网页源码

browser.page_source

4.在百度页面id为kw的输入框中输入book

driver.find_element_by_id('kw').send_keys('book’)

5.在百度页面id为kw的输入框中清除book

driver.find_element_by_id('kw’).clear()

6.在百度页面id为search的按钮点击搜索

a.driver.find_element_by_id('search').click()

b.action3 = self.driver.find_element_by_class_name('next')

ActionChains(self.driver).move_to_element(action3).double_click(action3).perform()

7.向前跳转回上一个页面

driver.back()

8.向后跳转回上一个页面

driver.forward()

9.关闭浏览器

browser.close() 关闭当前窗口

browser.quit() 退出并关闭窗口的每一个相关的驱动程序

10.获取某个元素的文本内容

driver.find_element_by_class_name("loading_btn").text

11.将浏览器窗口最大化显示

driver.maximize_window()

12.设置浏览器宽480、高800显示:

driver.set_window_size(480, 800)

13.获取验证码图片的大小

codeEelement = driver.find_element_by_id(‘code')

imgSize = codeEelement.size

14.获取验证码元素坐标

imgLocation = imgElement.location

15.计算验证码整体坐标

rangle = (int(imgLocation['x']),int(imgLocation['y']),int(imgLocation['x'] + imgSize['width']),int(imgLocation['y']+imgSize['height']))

注意:submit和click的区别。Click方法只适用于button,而submit可以用于提交表单。

2.4 获取元素的方法之find_element_by_css_selector

-----------------通过类class获取---------------

This heading is very important.

This paragraph is very important.

This paragraph is a very important warning.

1.获取class值为important的h1标签

find_element_by_css_selector(h1.importane)

2.获取所有class值为important的标签

find_element_by_css_selector(*.importane)或者find_element_by_css_selector(.importane)

3.获取class值为important warning的标签

find_element_by_css_selector(.importane.warning)

-----------------通过类ID获取---------------

This is a paragraph of introduction.

find_element_by_css_selector(#"intro")

-----------------属性选择器---------------

1.W3School

属性中包含了title和href,find_element_by_css_selector('a[title][href]’)

2About W3School

定位属性中href="http://www.w3school.com.cn/about_us.asp"的元素,

find_element_by_css_selector('a[href="http://www.w3school.com.cn/about_us.asp"]’)

3.W3School

通过href和title来定位

find_element_by_css_selector("a[href='http://www.w3school.com.cn/about_us.asp'][title='W3School']”)

-----------------部分属性定位---------------

可以应用样式:


无法应用样式:

定位title中包含有figure的元素:

find_element_by_css_selector("image[title~='figure']")

-----------------其他-------------------

[abc^="def"] 选择 abc 属性值以 "def" 开头的所有元素

[abc$="def"] 选择 abc 属性值以 "def" 结尾的所有元素

[abc*="def"] 选择 abc 属性值中包含子串 "def" 的所有元素

-----------------后代选择器--------------

This is a important heading

This is a important paragraph.

find_element_by_css_selector("h1 em")

2.5 获取元素的方法之find_element_by_xpath

这个方法是非常强大的元素查找方式,使用这种方法几乎可以定位到页面上的任意元素。在正式开始使用XPath进行定位前,我们先了解下什么是XPath。XPath是XML Path的简称,由于HTML文档本身就是一个标准的XML页面,所以我们可以使用XPath的语法来定位页面元素。

Xpath通过路径来定位控件,分为绝对路径和相对路径。绝对路径以单/号表示,相对路径则以//表示。当xpath的路径以/开头时,表示让Xpath解析引擎从文档的根节点开始解析。当xpath路径以//开头时,则表示让xpath引擎从文档的任意符合的元素节点开始进行解析。而当/出现在xpath路径中时,则表示寻找父节点的直接子节点,当//出现在xpath路径中时,表示寻找父节点下任意符合条件的子节点。弄清这个原则,就可以理解其实xpath的路径可以绝对路径和相对路径混合在一起来进行表示,想怎么玩就怎么玩。

快速获取你想要的元素xpath方式:

网页->检查->选中对应标签->右键选择copy->copy xpath

绝对路径写法(只有一种),写法如下:

引用页面上的form元素(即源码中的第3行):/html/body/form

下面是相对路径的引用写法:

查找页面根元素:

//

查找页面上所有的input元素:

//input

查找页面上第一个form元素内的直接子input元素(即只包括form元素的下一级input元素):

//form/input

查找页面上第一个form元素内的所有子input元素(只要在form元素内的input都算,不管还嵌套了多少个其他标签,使用相对路径表示,双//号):

//form//input

查找页面上第一个form元素:

//form

查找页面上id为loginForm的form元素:

//form[@id='loginForm']

查找页面上具有name属性为username的input元素:

//input[@name='username']

查找页面上id为loginForm的form元素下的第一个input元素:

//form[@id='loginForm']/input[1]

查找页面具有name属性为contiune并且type属性为button的input元素:

//input[@name='continue'][@type='button']

查找页面上id为loginForm的form元素下第4个input元素:

//form[@id='loginForm']/input[4]

以百度主页为例,搜索框的HTML示例代码如下,其xpath为//*[@id=''kw]。

获取元素的方法之find_element_by_css_selector

获取元素的方法之find_element_by_xpath

这两种方法来自于百度,方便大家更好的学习,我在这里借花献佛总结了一下放在了这里,因为我在写项目的时候记录笔记到了其他地方,具体的地址忘了,如果原创作者看到了,请留下你的地址。

三.代码展示

import re

import time

import pandas as pd

import pytesseract

from PIL import Image

from selenium import webdriver

from selenium.webdriver import ActionChains

from selenium.webdriver.support.wait import WebDriverWait

class CrackTouClick(object):

def __init__(self):

self.url = ""

self.search_url = ""

self.driver = webdriver.Chrome()

self.wait = WebDriverWait(self.driver, 20)

self.j_username = laosiji_username

self.j_password = laosiji_password

def open(self):

self.driver.get(self.url)

self.driver.find_element_by_name("j_username").send_keys(self.j_username)

self.driver.find_element_by_name("j_password").send_keys(self.j_password)

action3 = self.driver.find_element_by_id("code")

ActionChains(self.driver).move_to_element(action3).double_click(action3).perform()

def get_window_png(self):

ele = self.driver.find_element_by_class_name('logo')

ele.screenshot('ele.png')

def verification_code(self):

self.driver.maximize_window()

self.driver.save_screenshot('./element.png') # 截取当前网页,该网页有我们需要的验证码

rangle = (1434, 961, 1598, 1017) # 写成我们需要截取的位置坐标

element = Image.open("./element.png") # 打开截图

frame4 = element.crop(rangle) # 使用Image的crop函数,从截图中再次截取我们需要的区域

frame4.save('./code.png')

code = Image.open('./code.png')

text = pytesseract.image_to_string(code) # 使用image_to_string识别验证码

return text

def write(self):

while True:

code = self.verification_code()

# 判断验证码是否识别到且为4位数字与字母的字符串

if len(code.strip()) == 4 and code.isalnum():

self.driver.find_element_by_name("rand").send_keys(code)

break

else:

action3 = self.driver.find_element_by_id("rand_img")

ActionChains(self.driver).move_to_element(action3).double_click(action3).perform()

def login(self):

self.write()

login_action = self.driver.find_element_by_class_name("btn")

ActionChains(self.driver).move_to_element(login_action).double_click(login_action).perform()

# 判断是否有弹出框

def alert_is_present(self):

try:

alert = self.driver.switch_to.alert

print(alert)

return alert

except:

return False

def read(self):

while True:

self.login()

time.sleep(1)

# 如果有弹出框 点击确定

if self.alert_is_present():

self.driver.switch_to.alert.accept()

self.driver.switch_to.alert.accept()

time.sleep(1)

else:

break

time.sleep(1)

self.driver.get(self.search_url)

self.driver.quit()

三.开发中遇到的BUG

1.运行时chrome报错,终端打不开

File "/usr/local/python3/lib/python3.6/site-packages/selenium/webdriver/remote/errorhandler.py", line 242, in check_response

raise exception_class(message, screen, stacktrace)

selenium.common.exceptions.WebDriverException: Message: unknown error: Chrome failed to start: exited abnormally

(unknown error: DevToolsActivePort file doesn't exist)

(The process started from chrome location /usr/bin/google-chrome is no longer running, so ChromeDriver is assuming that Chrome has crashed.)

(Driver info: chromedriver=70.0.3538.97 (d035916fe243477005bc95fe2a5778b8f20b6ae1),platform=Linux 3.10.0-862.14.4.el7.x86_64 x86_64)

原因:运行过程中开启的进程太多

解决方法:如果你是mac,按 Command + 空格键来调出 Spotlight,输入 Activity Monitor 便可启动活动监视器。如果手动关闭几个名称为chromedriver的进程,然后再尝试打开终端,按进程名杀死进程输入killall chromedriver。

如果觉得不错,请留下您的大拇指哦👍

如果有什么疑问,请留下您的评论哦👍

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值