大概步骤
- 打开网页
- 输入账号、密码并且点击登录按钮
- 截图
- 获取验证码图片的坐标
- 裁剪验证码图片
- 使用接口,获得验证码坐标
- 按顺序点击验证码并且点击确定
每一步函数的代码
对象初始化
BIG_PATH = './big_path.jpg'
SMALL_PATH = './small_path.jpg'
img_code_obj = ""
url = '你猜猜~'
def __init__(self, username, password):
self.zb = None
self.username = username
self.password = password
self.page = None
打开网页
async def open_the_webpage(self):
'''
1.打开网页,并且输入账号密码,点击登录按钮
2.当验证码出来后,截取整个网页以及验证码
3.接入打码平台,获取验证码坐标数据
4.对验证码进行操作,并且点击确定
'''
# 启动 pyppeteer 属性设置
browser = await pyppeteer.launch(headless=False)
self.page = await browser.newPage()
await self.page.setViewport({'width': 1400, 'height': 800})
await self.page.goto(self.url)
# 登录
await self.login()
输入账号、密码并且点击登录按钮
async def login(self):
'''
进行登录操作
'''
# 等待页面加载完成
await self.page.waitFor('div[class="wel"]')
# 找到密码输入界面
button = await self.page.querySelector('div[class="one"]')
await button.click()
# 输入用户名和密码
await self.page.waitFor('input[placeholder="请输入账号"')
await self.page.type('input[placeholder="请输入账号"]', self.username, {'delay': 100})
await self.page.type('input[placeholder="请输入密码"]', self.password, {'delay': 100})
button = await self.page.querySelector('button[class="el-button btn el-button--default"]')
await button.click()
截图整个页面
async def intercept_a_web_page(self):
# 当验证码出来后,截取整个网页以及验证码
# 等待验证码出来
time.sleep(3)
# 截取整个网页
await self.page.screenshot({'path': self.BIG_PATH})
# 获取验证码图片坐标
await self.get_xpath_element()
获取验证码图片坐标
async def get_xpath_element(self):
# 获取验证码的element元素
el = await self.page.xpath("//div[starts-with(@style,'background-image: url')]")
self.zb = await el[0].boundingBox()
# 裁剪验证码图片
await self.image_shot()
裁剪验证码图片
async def image_shot(self):
# 截取一部分图片
left = int(self.zb['x'])
upper = int(self.zb['y'])
right = int(self.zb['x']) + int(self.zb['width'])
lower = int(self.zb['y']) + int(self.zb['height'])
# 打开一个文件
img = Image.open(self.BIG_PATH)
# 切图片
img_obj = img.crop((left, upper, right, lower))
# 保存图片
img_obj.save(self.SMALL_PATH)
# 使用接口,获得验证码坐标
coordinate = await self.base64_api()
# 按顺序点击验证码并点击确定
await self.image_click(coordinate)
使用接口,获得验证码坐标
async def base64_api(self, typeid=27):
with open(self.SMALL_PATH, 'rb') as f:
base64_data = base64.b64encode(f.read())
b64 = base64_data.decode()
data = {"username": 'sb9728',
"password": 'sb9728565',
"typeid": typeid,
"image": b64
}
reps = requests.post("https://api.ttshitu.com/predict", json=data)
if reps.status_code == 200:
result = reps.json()
return result
else:
return {'code': '-1'}
按顺序点击验证码并点击确定
async def image_click(self, coordinate):
result_list = coordinate['data']['result'].split('|')
# 操作鼠标点击指定坐标
for itme in result_list:
x = itme.split(',')[0]
y = itme.split(',')[1]
await self.page.mouse.click(int(self.zb['x']) + int(x), int(self.zb['y']) + int(y), {'delay': 500})
el = await self.page.xpath("//div[starts-with(@class,'geetest_submit_')]")
await el[0].click()
全部代码
import pyppeteer
import asyncio
import time
from PIL import Image
import base64
import requests
class auto_login:
BIG_PATH = './big_path.jpg'
SMALL_PATH = './small_path.jpg'
img_code_obj = ""
url = '你猜猜~'
def __init__(self, username, password):
self.zb = None
self.username = username
self.password = password
self.page = None
async def open_the_webpage(self):
'''
1.打开网页,并且输入账号密码,点击登录按钮
2.当验证码出来后,截取整个网页以及验证码
3.接入打码平台,获取验证码坐标数据
4.对验证码进行操作,并且点击确定
'''
# 启动 pyppeteer 属性设置
browser = await pyppeteer.launch(headless=False)
self.page = await browser.newPage()
await self.page.setViewport({'width': 1400, 'height': 800})
await self.page.goto(self.url)
# 登录
await self.login()
async def login(self):
'''
进行登录操作
'''
# 等待页面加载完成
await self.page.waitFor('div[class="wel"]')
# 找到密码输入界面
button = await self.page.querySelector('div[class="one"]')
await button.click()
# 输入用户名和密码
await self.page.waitFor('input[placeholder="请输入账号"')
await self.page.type('input[placeholder="请输入账号"]', self.username, {'delay': 100})
await self.page.type('input[placeholder="请输入密码"]', self.password, {'delay': 100})
button = await self.page.querySelector('button[class="el-button btn el-button--default"]')
await button.click()
# 截图
await self.intercept_a_web_page()
async def intercept_a_web_page(self):
# 当验证码出来后,截取整个网页以及验证码
# 等待验证码出来
time.sleep(3)
# 截取整个网页
await self.page.screenshot({'path': self.BIG_PATH})
# 获取验证码图片坐标
await self.get_xpath_element()
async def get_xpath_element(self):
# 获取验证码的element元素
el = await self.page.xpath("//div[starts-with(@style,'background-image: url')]")
self.zb = await el[0].boundingBox()
# 裁剪验证码图片
await self.image_shot()
async def image_shot(self):
# 截取一部分图片
left = int(self.zb['x'])
upper = int(self.zb['y'])
right = int(self.zb['x']) + int(self.zb['width'])
lower = int(self.zb['y']) + int(self.zb['height'])
# 打开一个文件
img = Image.open(self.BIG_PATH)
# 切图片
img_obj = img.crop((left, upper, right, lower))
# 保存图片
img_obj.save(self.SMALL_PATH)
# 使用接口,获得验证码坐标
coordinate = await self.base64_api()
# 按顺序点击验证码并点击确定
await self.image_click(coordinate)
async def image_click(self, coordinate):
result_list = coordinate['data']['result'].split('|')
# 操作鼠标点击指定坐标
for itme in result_list:
x = itme.split(',')[0]
y = itme.split(',')[1]
await self.page.mouse.click(int(self.zb['x']) + int(x), int(self.zb['y']) + int(y), {'delay': 500})
el = await self.page.xpath("//div[starts-with(@class,'geetest_submit_')]")
await el[0].click()
async def base64_api(self, typeid=27):
with open(self.SMALL_PATH, 'rb') as f:
base64_data = base64.b64encode(f.read())
b64 = base64_data.decode()
data = {"username": 'sb9728',
"password": 'sb9728565',
"typeid": typeid,
"image": b64
}
reps = requests.post("https://api.ttshitu.com/predict", json=data)
if reps.status_code == 200:
result = reps.json()
return result
else:
return {'code': '-1'}
async def click_on_the_welfare_society(self):
el = await self.page.xpath("//li[@index='9']")
await el[0].click()
time.sleep(10)
async def main():
'''
1.打开网页
2.输入账号、密码
3.点击登录按钮
4.截图
5.获取验证码图片的坐标
6.裁剪验证码图片
7.使用接口,获得验证码坐标
8.按顺序点击验证码
9.点击确定
'''
username = '你猜猜~'
password = '你猜猜~'
auto = auto_login(username, password)
# 打开网页
await auto.open_the_webpage()
if __name__ == '__main__':
x = asyncio.ensure_future(main())
asyncio.get_event_loop().run_until_complete(x)
注意点
- 这个自动登录,由于我刚接触 Python 爬虫的时候,是教的 pypeteer,所以是用的 pypeteer,同样的操作用 selenium 也是可以的,思路是一样的。
- pypeteer好像因为是异步的原因,导致不能在主函数处把每一步一个一个列出来,会导致同时进行而出现错误。
目前我就是用递推的方式,在每一个函数的最后调用了下一步函数。
不过这样总归是看着不够整洁,如果有大佬知道怎么解决这个问题的话,可以评论或私信。