一、selenium的使用
selenium库是python用来实现浏览器自动化操作,除了pip install selenium
还要下载浏览器的驱动才能实现最终效果,最开始看的教程是关于PhantomJS 一个无头浏览器驱动,但是发现已经宣布不和python联动了,这里帮大家避下雷(时代变了
我选用的是chrome的驱动,相关下载以及安装步骤如下链接:
http://blog.csdn.net/huilan_same/article/details/51896672
下载下来后把里面的exe文件放到当前选用编辑器的python.exe同一个文件目录下面,然后用命令提示符运行start chromedriver
如果跳出如下字样证明驱动运行成功:
Please see https://chromedriver.chromium.org/security-considerations for suggestions on keeping ChromeDriver safe.
ChromeDriver was started successfully
详细关于selenium的操作查看https://blog.csdn.net/qq_41341757/article/details/109992140
注意:在使用selenium访问网页时,很多网页都是由多个<frame>
或<iframe>
组成,而webdriver默认定位的是最外层的frame
, 所以如果要找的网页元素在下一个frame
中的话,我们首先需要转换一下
driver.switch_to.frame("login_frame")
关于<frame>
:一个HTML页面可以有一个或多个子框架,这些子框架以<iframe>
来标记,用来显示一个独立的HTML页面。如果有了解的兴趣:https://blog.csdn.net/diaojinxun8373/article/details/101491545
二、用selenium获取验证码图片
先通过网页解析将获取到的验证码下载到本地:
我们运用selenium的库把网页进行截屏然后通过解析网页了解验证码所在的位置,通过截取方法在整张图片中获得验证码
from selenium import webdriver
from PIL import Image
if __name__ == '__main__':
#创建一个浏览器实例并访问页面
wbe = webdriver.Chrome()
wbe.get("http://ybt.ssoier.cn:8088/")
time.sleep(2)
#这个网站需要点击一个按钮才能显示验证码,我们要先通过find_element_by_xpath找到他
enter = wbe.find_element_by_xpath('/html/body/center/table[1]/tbody/tr/th[3]/a[1]')
#对他进行点击操作
enter.click()
#将整个屏幕截取下来
wbe.save_screenshot("das.png")
#定位验证码位置
element = wbe.find_element_by_xpath('/html/body/center/table[1]/tbody/tr/th[3]/form/table/tbody/tr[3]/td/img')
left = element.location['x']
top = element.location['y']
right = element.location['x'] + element.size['width']
bottom = element.location['y'] + element.size['height']
#根据位置进行截屏操作
im = Image.open(r'das.png')
im = im.crop((left * 1.25, top * 1.25, right * 1.25, bottom * 1.25))
im.save('a.png')
关于selenium中的element_by_xpath操作https://blog.csdn.net/u012941152/article/details/83011110
建议在浏览器中右击要查找的按钮点击检查,在对应的区块代码右键选择copy/copy full path然后直接复制到.find_element_by_xpath()
中就可以实现查找
注意:这里如果是通过显示出来截屏的需要注意一下是否显示屏是经过缩放的,这个在windows的设置-显示-缩放与布局里可以看,如果是经过缩放的,最后截屏的所有参数也都要乘一个缩放的倍数,但如果是*面的浏览模式就不用在意这点。
三、关于验证码识别出错弹窗处理
借鉴于:https://blog.csdn.net/kelanmomo/article/details/82886374
因为识别验证码出错会导致登录失败,有些网站会弹出窗口提示验证码输入错误,要点击确定才能进行下一步操作,比如http://ybt.ssoier.cn:8088/
from selenium import webdriver
from selenium.webdriver.support import expected_conditions as EC
#创建浏览器实例
wbe = webdriver.Chrome()
wbe.get("http://ybt.ssoier.cn:8088/")
#判断是否有弹窗弹出
result = EC.alert_is_present()(wbe)
if result:
time.sleep(2)
alert = wbe.switch_to.alert # 切换到alert
print('alert text : ' + alert.text) # 打印alert的文本
alert.accept() # 点击alert的【确认】按钮
else :
print("登录成功")
wbe.save_screenshot("sucessful.png")
四、关于验证码识别
线下关于验证码处理主要认为有Tesseract-OCR、人工打码平台、机器学习、直接用cookie登录、万能识别库等方法,下面几种为本人所查阅资料去了解的
①通过代码逐步处理得到的二维码图片:https://blog.csdn.net/qq_39620871/article/details/80732521因为成功概率不大,大家有兴趣可以去看看玩玩。
②通过外带的api进行验证码的识别,这种一般都会有收取一点费用,但是也一般会提供相关的文档帮助你上手,这边看到很多博客中都推荐了八爪鱼、超级鹰、百度的ocr技术(部分不用收费)
具体可转看:https://blog.csdn.net/bmx_rikes/article/details/82357077 或直接搜python打码平台)
这边是依据这篇博客进行操作:https://blog.csdn.net/qqjinxiaolei/article/details/100707047
下载提供的软件后打开服务器,在ip中输入127.0.0.1
表示自己的计算机,开启服务器
def orc(file_name):
path=os.path.abspath('.') +'\\'+ file_name #注意python的\会被当成转义字符所以要\\来显示\
url = "http://127.0.0.1:5658/?visualbendi="+path
headers = {'User-Agent': my_fake_useragent.UserAgent().random()}
html = requests.get(url=url, headers=headers)
result = html.text
final_result = re.findall(re.compile(r'<div class="code">(.*?)</div>'), result)[0]
return final_result
其他可以看看https://blog.csdn.net/kerlomz/article/details/105974823 据评论说识别率挺高,有兴趣也可以按照文章中的线索自己开发
五、实践代码
这里以一本通的网站为对象尝试进行登录http://ybt.ssoier.cn:8088/ (毕竟是难忘的痛
代码如下:
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.support import expected_conditions as EC
import my_fake_useragent
from PIL import Image
import requests
from hashlib import md5
import time
import pytesseract
import os
import re
def orc(file_name):
path=os.path.abspath('.') +'\\'+ file_name
url = "http://127.0.0.1:5658/?visualbendi="+path
headers = {'User-Agent': my_fake_useragent.UserAgent().random()}
html = requests.get(url=url, headers=headers)
result = html.text
final_result = re.findall(re.compile(r'<div class="code">(.*?)</div>'), result)[0]
return final_result
if __name__ == '__main__':
#wbe = webdriver.Chrome()
#无头
chrome_options = Options()
chrome_options.add_argument('--headless')
chrome_options.add_argument('--disable-gpu')
wbe = webdriver.Chrome( chrome_options=chrome_options)
#点击登录按钮
wbe.get("http://ybt.ssoier.cn:8088/")
time.sleep(1)
while(1):
enter = wbe.find_element_by_xpath('/html/body/center/table[1]/tbody/tr/th[3]/a[1]')
enter.click()
#输入账号密码
search_id = wbe.find_element_by_xpath('/html/body/center/table[1]/tbody/tr/th[3]/form/table/tbody/tr[1]/td/input')
search_password = wbe.find_element_by_xpath('/html/body/center/table[1]/tbody/tr/th[3]/form/table/tbody/tr[2]/td/input')
search_id.send_keys('put_id')
search_password.send_keys('put_password')
#处理验证码
wbe.save_screenshot("das.png")
element = wbe.find_element_by_xpath('/html/body/center/table[1]/tbody/tr/th[3]/form/table/tbody/tr[3]/td/img')
left = element.location['x']
top = element.location['y']
right = element.location['x'] + element.size['width']
bottom = element.location['y'] + element.size['height']
im = Image.open(r'das.png')
#im = im.crop((left*1.25, top*1.25, right*1.25, bottom*1.25))
im = im.crop((left,top,right,bottom))
im.save('a.png')
#输入验证码
search_mark = wbe.find_element_by_xpath('/html/body/center/table[1]/tbody/tr/th[3]/form/table/tbody/tr[3]/td/input')
search_mark.send_keys(str(orc('a.png')))
#登录
search_login = wbe.find_element_by_xpath('/html/body/center/table[1]/tbody/tr/th[3]/form/table/tbody/tr[4]/td[2]/input')
search_login.click()
result = EC.alert_is_present()(wbe)
if result:
time.sleep(2)
alert = wbe.switch_to.alert # 切换到alert
print('alert text : ' + alert.text) # 打印alert的文本
alert.accept() # 点击alert的【确认】按钮
continue # 如果验证码输入错误再进行尝试
else :
print("登录成功")
wbe.save_screenshot("sucessful.png")
wbe.quit()
break
运行后有一处警告,但是最后登录成功,代码也是实现完全的,关于警告这里大家如果有什么答案希望能交流
关于其他验证码的方法参考:
触点选验证码 https://blog.csdn.net/qq_42992919/article/details/98483845
滑动验证码:https://blog.csdn.net/wzyaiwl/article/details/89603059
六、关于cookie
许多网页需要通过post方法在登陆时给我们传一个cookie,我们需要一个变量来接受传来的cookie避免登录的失败,这里我们选用session方法进行保存(应用requests库即可)。
如果在请求过程中产生cookie会被自动储蓄在这个session对象中,而如果直接用get方法访问网站,他会自动将cookie带上,以下为操作代码:
import requests
#---转自https://blog.csdn.net/haeasringnar/article/details/82558729-----#
session = requests.Session()#新建session会话对象
post_url = 'https://passport.weibo.cn/sso/login'
# 往下使用requests的地方,直接使用session即可,session就会保存服务器发送过来的cookie信息
headers = {省略....}
data = {
'username': '17312345678', # 账号
'password': 'password', # 密码
'savestate': '1',
.......以及其他表单参数
}
r = session.post(url=post_url, data=data, headers=headers)
# 上面的session会保存会话,往下发送请求,直接使用session即可
url = 'https://weibo.cn/6388179289/info'
headers1 = {
'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.108 Safari/537.36',
}
r = session.get(url=url, headers=headers1)
print(r.text)
通过cookiejar
对cookie进行保存使用:https://blog.csdn.net/u011486491/article/details/82973403
通过session
自动获取cookie:https://blog.csdn.net/qq_30175203/article/details/52105082
七、通过cookie跳过验证登录
推荐:https://blog.csdn.net/weixin_37719937/article/details/97417842
而关于自动获取cookie的操作:https://blog.csdn.net/mouday/article/details/80137852
一般cookie的格式为:
Set-Cookie:NAME=VALUE:Expires/Max-age=DATE;Path=PATH;Domain=DONAIIN_NAME;SECURE
参数意义:
- NAME:cookie的名字。
- VALUE:cookie的值。
- Expires:cookie的过期时间。
- Path:cookie作用的路径。
- Domain:cookie作用的域名。
- SECURE:是否只在https协议下起作用。