前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >模拟登录12306和教务系统

模拟登录12306和教务系统

作者头像
y191024
发布2022-09-20 19:19:42
7690
发布2022-09-20 19:19:42
举报
文章被收录于专栏:睡不着所以学编程

今天学习如何自动登录12306,但是有点难,很多东西不是很知道原理,视频里的老师也有很多是直接粘贴过来的代码。

先来看看效果叭!速度有加快,实际上没那么快识别:

首先,打开12306的网页,看一下该如何自动登录。

这个就是刚进入时的页面,默认是二维码扫码的界面,我们要将他切换成账号密码登录。

切换完以后,会发现下面有一个验证码,这个时候就又要用到我们的超级鹰了,但是我们会发现得到的爬取到的图片的src是空值,这是因为验证码是动态加载的,每一次打开都是不一样的,此时我们的思路就是将整个页面截取下来,然后再截取出验证码部分的图片,放在文件中,然后用超级鹰去破解验证码。

首先,我们找到超级鹰的源码,将他粘贴到我们的文件中方便直接使用。

代码语言:javascript
复制
#!/usr/bin/env python
# coding:utf-8
import requests
from hashlib import md5

class 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()

chaojiying = Chaojiying_Client('4415232000', '4415232000', '915722')  # 用户中心>>软件ID 生成一个替换 96001
im = open('png.jpg', 'rb').read()  # 本地图片文件路径 来替换 a.jpg 有时WIN系统须要//
print(chaojiying.PostPic(im, 9004)['pic_str'])  # 1902 验证码类型  官方网站>>价格体系 3.4+版 print 后要加())

在下面开始打我们的代码。

下面是这次要用到的包

代码语言:javascript
复制
from selenium import webdriver
from selenium.webdriver import ActionChains
from time import sleep
from PIL import Image  # 截取图片用的

接下来访问12306网页

代码语言:javascript
复制
# 创建一个浏览器实例
bro = webdriver.Chrome(executable_path="chromedriver.exe")
# 浏览器窗口最大化
bro.maximize_window()
bro.get("https://kyfw.12306.cn/otn/resources/login.html")
sleep(1)

再找到“账号登录”的标签,点击切换到账号密码登录。

代码语言:javascript
复制
login = bro.find_element_by_css_selector("body > div.login-panel > div.login-box > ul > li.login-hd-account > a")
login.click()
sleep(2)

此时的界面是这样的

现在要就要截取整个屏幕了,这里用到的方法是save_screenshot(“图片保存路径”)

代码语言:javascript
复制
bro.save_screenshot("./aa.png")

运行后看看结果:

成功截取到了整个页面,但是要记得先将浏览器窗口最大化,使用maximize_window()来实现(在上面的代码中已经用到)。

现在对验证码的位置做个定位,在这里,图片的location应该是图片左上角的坐标,所有它的右下角的x坐标就是location中的x加上图片大小中的宽度,图片右下角的y坐标应该是location中的y坐标加上图片的高度

代码语言:javascript
复制
code_img = bro.find_element_by_id("J-loginImg")
location = code_img.location  # 验证码左上角的x,y坐标
size = code_img.size  # 宽度
c = (int(location["x"]),int(location["y"]),int(location["x"]+int(size["width"])),
int(location["y"])+int(size["height"]))

那么接下来就要在我们保存的这张图片的基础上裁剪出验证码的图片,需要用到的是PIL中的Image库。

代码语言:javascript
复制
i = Image.open("aa.png")
code_img_name = "code.png"
frame = i.crop(rangle)
frame.save(code_img_name)

现在就把验证码给裁剪了出来

接下来只要让超级鹰去识别我们保存的验证码图片就可以了.

我们会发现,超级鹰返回的是要点击的图片的坐标,而且是用"|"符号隔开的,比如 112,98|36,94,所以我们要用split方法将两个坐标分别取出,然后再将他们的x,y也分别取出,放进一个列表中,最后再将这些列表放入all_list这个大的列表中中,遍历这个总的列表,就可以得到每个坐标了(这里有点复杂,还需要多理解下)

代码语言:javascript
复制
all_list = []
if "|" in result:
    list1 = result.split("|")
    print(list1)
    count1 = len(list1)
    for i in range(count1):
        xy_list = []
        x = int(list1[i].split(",")[0])
        y = int(list1[i].split(",")[1])
        xy_list.append(x)
        xy_list.append(y)
        all_list.append(xy_list)
else:
    x = int(result.split(",")[0])
    y = int(result.split(",")[1])
    xy_list = []
    xy_list.append(x)
    xy_list.append(y)
    all_list.append(xy_list)

for l in all_list:
    x = l[0]
    y = l[1]
    ActionChains(bro).move_to_element_with_offset(code_img, x, y).click().perform()
    sleep(1)

我们还要输入账号和密码.

代码语言:javascript
复制
username = bro.find_element_by_id("J-userName")
username.send_keys("166****2464")
pwd = bro.find_element_by_id("J-password")
pwd.send_keys("*********")

差不多就这样,最后贴一个完整的代码,靠这个方法也成功的登录了学校的教务系统.

代码语言:javascript
复制
#!/usr/bin/env python
# coding:utf-8
import requests
from hashlib import md5


class 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()


from selenium import webdriver
from selenium.webdriver import ActionChains
from time import sleep
from PIL import Image

# 创建一个浏览器实例
bro = webdriver.Chrome(executable_path="chromedriver.exe")
# 浏览器窗口最大化
bro.maximize_window()
bro.get("https://kyfw.12306.cn/otn/resources/login.html")
sleep(0.2)
login = bro.find_element_by_css_selector("body > div.login-panel > div.login-box > ul > li.login-hd-account > a")
login.click()
sleep(2)
# 截取屏幕
bro.save_screenshot("./aa.png")
code_img = bro.find_element_by_id("J-loginImg")
location = code_img.location  # 验证码左上角的x,y坐标
size = code_img.size  # 宽度
rangle = (int(location["x"]), int(location["y"]), int(location["x"] + int(size["width"])),
          int(location["y"]) + int(size["height"]))

# 局部区域裁剪
i = Image.open("./aa.png")
code_img_name = "./code.png"
frame = i.crop(rangle)
frame.save(code_img_name)

username = bro.find_element_by_id("J-userName")
username.send_keys("166****2464")
pwd = bro.find_element_by_id("J-password")
pwd.send_keys("************")

chaojiying = Chaojiying_Client('4415232000', '4415232000', '915722')  # 用户中心>>软件ID 生成一个替换 96001
im = open('code.png', 'rb').read()  # 本地图片文件路径 来替换 a.jpg 有时WIN系统须要//
result = chaojiying.PostPic(im, 9004)['pic_str']  # 1902 验证码类型  官方网站>>价格体系 3.4+版 print 后要加())

all_list = []
if "|" in result:
    list1 = result.split("|")
    print(list1)
    count1 = len(list1)
    for i in range(count1):
        xy_list = []
        x = int(list1[i].split(",")[0])
        y = int(list1[i].split(",")[1])
        xy_list.append(x)
        xy_list.append(y)
        all_list.append(xy_list)
else:
    x = int(result.split(",")[0])
    y = int(result.split(",")[1])
    xy_list = []
    xy_list.append(x)
    xy_list.append(y)
    all_list.append(xy_list)

for l in all_list:
    x = l[0]
    y = l[1]
    ActionChains(bro).move_to_element_with_offset(code_img, x, y).click().perform()
    sleep(1)

login_button = bro.find_element_by_id("J-login")
login_button.click()
sleep(1)
block = bro.find_element_by_id("nc_1_n1z")
action = ActionChains(bro)

action.click_and_hold(block)

action.move_by_offset(300, 0).perform()
sleep(0.5)

sleep(5)

bro.quit()

教务系统登录的原理也差不多,而且更加简单,因为不是点击图片,知识简单的识别数字验证码.

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-05-19,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 睡不着所以学编程 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
验证码
腾讯云新一代行为验证码(Captcha),基于十道安全栅栏, 为网页、App、小程序开发者打造立体、全面的人机验证。最大程度保护注册登录、活动秒杀、点赞发帖、数据保护等各大场景下业务安全的同时,提供更精细化的用户体验。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档