黑马程序员技术交流社区
标题:
【上海校区】模拟登陆 12306网站
[打印本页]
作者:
梦缠绕的时候
时间:
2019-10-18 14:03
标题:
【上海校区】模拟登陆 12306网站
准备
目标网站 :
https://kyfw.12306.cn/otn/login/init
安装PIL模块: pip3 install pillow 或 pip3 --default-timeout=100 install -U pillow 第三方图像处理库(图片定位裁剪)准备一个浏览器驱动(版本不要差太多) chromedriver.exe 下载:
https://npm.taobao.org/mirrors/chromedriver/
验证码识别网站(超级鹰):
http://www.chaojiying.com/
需要注册,使用方法 参考
#页面中验证码识别;
https://www.cnblogs.com/guokaifeng/p/11536706.html
需求分析
通过selenium模块来实现模拟登录- 难点:对验证码的自动识别(验证码要一次获取,刷新的话会更改验证码)- 解决方案:对验证码区域进行截取(使用PIL模块的Image),用超级鹰来获取正确验证码的坐标,然后由selenium实现登录
实现代码
from
PIL
import
Image
#导入Image截图
from
time
import
sleep
from
selenium
import
webdriver
from
Cjy
import
Chaojiying_Client
# 导入超级鹰验证码识别
from
selenium.webdriver
import
ActionChains
# 导入ActionChains动作链
bro = webdriver.Chrome(executable_path=
'chromedriver.exe'
)
# 指定浏览器驱动
bro.get(
'https://kyfw.12306.cn/otn/login/init'
)sleep(3)
# 防止网络(慢)原因图片加载失败
bro.save_screenshot(
'main.png'
)
# 截取显示页面
# 对页面中的验证码图片做定位
code_img_tag = bro.find_element_by_xpath(
'//*[@id="loginForm"]/div/ul[2]/li[4]/div/div/div[3]/img'
)
# 定位到验证码图片的标签
location = code_img_tag.location
# 图片坐标(左下,右上) {'x':274,'y':293}
size = code_img_tag.size
# 图片的宽高 {'height':190,'width':293}
# 裁剪的区域范围 (矩获取验证码的图片)
rangle = (int(location[
'x'
]),int(location[
'y'
]),int(location[
'x'
]+size[
'width'
]),int(location[
'y'
]+size[
'height'
]))
# 使用Image裁剪出验证码图片 code.png
i = Image.open(
'./main.png'
)frame = i.crop(rangle)frame.save(
'code.png'
)
# 调用超级鹰对图片进行识别
def get_text(imgPath,imgType): chaojiying = Chaojiying_Client(
'账户'
,
'密码'
,
'软件id'
)
#超级鹰的账户密码软件码 注意最少要充1元才能使用
im = open(imgPath,
'rb'
).read()
return
chaojiying.PostPic(im, imgType)[
'pic_str'
]result = get_text(
'./code.png'
,9004)
# 传入验证码与验证码类型 返回值为正确图片的坐标55,70|267,133 (账户不对或没有余额 会报错)
# 把图片坐标转换为 55,70|267,133 ==[[55,70],[267,133]]
all_list = []lis = result.split(
'|'
)
#['55,70', '267,133']
all_list.append([int(a)
for
a
in
lis[0].split(
','
)])all_list.append([int(a)
for
a
in
lis[-1].split(
','
)])
# 让动作链去指定验证码区域模拟鼠标点击
for
a
in
all_list: x = a[0] y = a[1] ActionChains(bro).move_to_element_with_offset(code_img_tag,x,y).click().perform()
break
bro.find_element_by_id(
'username'
).send_keys(
'123456'
)
# 输入12306账户
bro.find_element_by_id(
'password'
).send_keys(
'67890000000'
)
# 输入密码
bro.find_element_by_id(
'loginSub'
).click()
# 点击登录
sleep(5)bro.quit()
#退出
# 超级鹰代码
import
requests
from
hashlib
import
md5class Chaojiying_Client(object): def __init__(self, username, password, soft_id): self.username = username password = password.encode(
'utf8'
) self.password = md5(password).hexdigest() self.soft_id = soft_id self.base_params = {
'user'
: self.username,
'pass2'
: self.password,
'softid'
: self.soft_id, } self.headers = {
'Connection'
:
'Keep-Alive'
,
'User-Agent'
:
'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0)'
, } def PostPic(self, im, codetype):
""" im: 图片字节 codetype: 题目类型 参考
http://www.chaojiying.com/price.html
"""
params = {
'codetype'
: codetype, } params.update(self.base_params) files = {
'userfile'
: (
'ccc.jpg'
, im)} r = requests.post(
'http://upload.chaojiying.net/Upload/Processing.php'
, data=params, files=files, headers=self.headers)
return
r.json() def ReportError(self, im_id):
""" im_id:报错题目的图片ID """
params = {
'id'
: im_id, } params.update(self.base_params) r = requests.post(
'http://upload.chaojiying.net/Upload/ReportError.php'
, data=params, headers=self.headers)
return
r.json()
作者:
梦缠绕的时候
时间:
2019-10-18 14:03
有任何问题欢迎在评论区留言
作者:
梦缠绕的时候
时间:
2019-10-18 14:03
或者添加学姐微信
DKA-2018
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/)
黑马程序员IT技术论坛 X3.2