一个网页不需要登录,就可以随意访问网站的所有具体信息的话,那就好比是一个敞开了大门的网站,摆好酒桌好吃好喝招待爬虫脚本们,数据提取的成本非常低。于是比较常规的网站,都会使用账号登录来提高网站对于每个想要查看网站数据的门槛,所以模拟登陆的问题就是必修课
我目前接触到的模拟登录方式就两种,一个是解析登录接口,查看具体提交的表单,密码的加密方式,用到的一般是request这样的库。优点是运行快,缺点是开发成本大;第二个就是selenium这种自动化测试工具模拟一个正常用户的具体登录操作:打开,鼠标移动、点击,输入账号密码,最后点击登录,这种方式的有点是省事,不需要慢慢查看具体提交的表单信息,但在缺点上除了运行慢之外,一般还有一个不小的麻烦,就是形式复杂的验证码。
说实话第一种实现方式,过于复杂,基本没有接触(对于大流量网站),于是主要还是说明第二种实现方式:selenium库和验证码破解
selenium的模拟操作上,无非就是webdriver.find_element_by_XXX("")找到某个input元素,用.send_keys("user or password")输入后,使用.click()来点击登录,这上面一般没有问题。
但是最大的麻烦一般就会在.click()操作后出现,那就是验证码...
注意
图片缺失:
2020/08/weibo_V.png原因:uploads 归档中不存在此路径的文件 原链接:https://kutake.site/wp-content/uploads/2020/08/weibo_V.png
比如微博的验证码
当你打开F12,找到验证码的请求url时,会发现一个问题,那就是每次请求返回的图片结果都不一样,所以我们使用selenium的截图功能来实现
具体流程:
- 打开页面
- 输入账号密码
- 点击登录弹出验证码
webdriver.save_screenshot截全图- find定位验证码元素
.location获取验证码元素坐标- 依据坐标使用
.crop剪裁 - 得到的图片使用云打码平台等识别验证码
- 输入,点击登录
验证码处理
如果使用靠谱的打码平台,那可能不需要使用这种手段对得到的验证码图片进行处理,但如果是使用百度阿里等图片识别平台,那就需要进行转灰和二值化验证码操作
注意
图片缺失:
2020/08/convert_ver.png原因:uploads 归档中不存在此路径的文件 原链接:https://kutake.site/wp-content/uploads/2020/08/convert_ver.png
普通验证码转灰
注意
图片缺失:
2020/08/convert.jpg原因:uploads 归档中不存在此路径的文件 原链接:https://kutake.site/wp-content/uploads/2020/08/convert.jpg
转灰
注意
图片缺失:
2020/08/pcode.jpg原因:uploads 归档中不存在此路径的文件 原链接:https://kutake.site/wp-content/uploads/2020/08/pcode.jpg
复杂背景验证码
就像这样
可以方便模型更好识别出文字,字母或者数字
代码
#weibo_login_sele.py
from selenium import webdriver
import time
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait
import requests
from selenium.common.exceptions import NoSuchElementException
from PIL import Image
import matplotlib.pyplot as plt
from aip import AipOcr
def main():
test_webdriver = webdriver.Chrome()
test_webdriver.maximize_window()
test_webdriver.get("https://weibo.com/login.php")
user="user"
passwd = "pass"
element_user = WebDriverWait(test_webdriver,5,0.5).until(EC.presence_of_element_located((By.XPATH,"//input[@id='loginname']")))
time.sleep(0.5)
element_user.send_keys(user)
element_pw = WebDriverWait(test_webdriver,5,0.5).until(EC.presence_of_element_located((By.XPATH,"//input[@name='password']")))
time.sleep(0.5)
element_pw.click()
time.sleep(0.5)
element_pw.send_keys(passwd)
#test_webdriver.find_element_by_xpath("//a[@node-type='submitBtn']").click()
time.sleep(2.5)
e = test_webdriver.find_element_by_xpath("//img[@node-type='verifycode_image']")
time.sleep(0.5)
img = "weibo.png"
element_verify = e
time.sleep(1)
test_webdriver.save_screenshot(img)
print(element_verify.location)
print(element_verify.size)
left = element_verify.location['x']
top = element_verify.location['y']
right = element_verify.location['x'] + element_verify.size['width']
bottom = element_verify.location['y'] + element_verify.size['height']
im = Image.open(img)
verifycode_image = im.crop((left,top,right,bottom))
ver = verifycode_image.convert("L")
ver.save("convert_ver.png")
get_api()
#test_webdriver.quit()
#saveImgLight()
def saveImgLight():
im = Image.open("code.jpg")
#plt.imshow(im)
#plt.show()
im1 = im.crop((0,0,344,343))
im2 = im.crop((0,343,115,382))
im2.save("word.jpg")
im1.save("pcode.jpg")
#转灰
im3 = im1.convert("L")
im3.save("convert.jpg")
#二值化
#im4 = im1.point(lambda p:p * 4)
#im4.save("point.jpg")
def get_api():
APP_ID = 'ID'
API_KEY = 'KEY'
SECRET_KEY = 'S_KEY'
client = AipOcr(APP_ID, API_KEY, SECRET_KEY)
options = {}
with open("convert_ver.png","rb") as f1:
p1=f1.read()
#with open("word.jpg","rb") as f2:
#p2=f2.read()
options["language_type"] = "ENG"
lo1 = client.accurate(p1,options)
#lo2 = client.accurate(p2,options)
print(lo1)
#print(lo2)
main()