(七) 验证码处理

引入

  • 相关的门户网站在进行登录的时候,如果用户连续登录的次数超过3次或者5次的时候,就会在登录页中动态生成验证码。通过验证码达到分流和反爬的效果。

今日概要

  • 使用云打码平台识别验证码

知识点回顾

  • session的创建方式
  • session的作用
  • proxies参数的作用
  • 高匿,透明代理的区别

今日内容

云打码平台处理验证码的实现流程:

- 1.对携带验证码的页面数据进行抓取
- 2.可以将页面数据中验证码进行解析,验证码图片下载到本地
- 3.可以将验证码图片提交给三方平台进行识别,返回验证码图片上的数据值
    - 云打码平台:
        - 1.在官网中进行注册(普通用户和开发者用户)
        - 2.登录开发者用户:
            - 1.实例代码的下载(开发文档-》调用实例及最新的DLL-》PythonHTTP实例下载)
            - 2.创建一个软件:我的软件-》添加新的软件
        -3.使用示例代码中的源码文件中的代码进行修改,让其识别验证码图片中的数据值

代码展示:

# 该函数就调用了打码平台的相关的接口对指定的验证码图片进行识别,返回图片上的数据值
def getCode(codeImg):
    # 云打码平台普通用户的用户名
    username    = 'bobo328410948'

    # 云打码平台普通用户的密码
    password    = 'bobo328410948'                            
    
    # 软件ID,开发者分成必要参数。登录开发者后台【我的软件】获得!
    appid       = 6003                                     

    # 软件密钥,开发者分成必要参数。登录开发者后台【我的软件】获得!
    appkey      = '1f4b564483ae5c907a1d34f8e2f2776c'    

    # 验证码图片文件
    filename    = codeImg                        

    # 验证码类型,# 例:1004表示4位字母数字,不同类型收费不同。请准确填写,否则影响识别率。在此查询所有类型 http://www.yundama.com/price.html
    codetype    = 3000

    # 超时时间,秒
    timeout     = 20                                    

    # 检查
    if (username == 'username'):
        print('请设置好相关参数再测试')
    else:
        # 初始化
        yundama = YDMHttp(username, password, appid, appkey)

        # 登陆云打码
        uid = yundama.login();
        print('uid: %s' % uid)

        # 查询余额
        balance = yundama.balance();
        print('balance: %s' % balance)

        # 开始识别,图片路径,验证码类型ID,超时时间(秒),识别结果
        cid, result = yundama.decode(filename, codetype, timeout);
        print('cid: %s, result: %s' % (cid, result))
        
        return result

 使用云打码平台模拟登录案例

# 古诗文网携带验证码的模拟登录
# 1.识别验证码
import requests
from lxml import etree
from code_class import YDMHttp
requests = requests.Session()


def get_code_text(code_type, file_path):
    result = None
    
    # 普通用户名
    username    = 'username'

    # 密码
    password    = 'password'

    # 软件ID,开发者分成必要参数。登录开发者后台【我的软件】获得!
    appid       = 7971

    # 软件密钥,开发者分成必要参数。登录开发者后台【我的软件】获得!
    appkey      = 'b6fef487706d29041c20e6f9da220669'

    # 图片文件
    filename    = file_path

    # 验证码类型,# 例:1004表示4位字母数字,不同类型收费不同。请准确填写,否则影响识别率。在此查询所有类型 http://www.yundama.com/price.html
    codetype    = code_type

    # 超时时间,秒
    timeout     = 30

    # 检查
    if (username == 'username'):
        print('请设置好相关参数再测试')
    else:
        # 初始化
        yundama = YDMHttp(username, password, appid, appkey)

        # 登陆云打码
        uid = yundama.login();
        print('uid: %s' % uid)

        # 查询余额
        balance = yundama.balance();
        print('balance: %s' % balance)

        # 开始识别,图片路径,验证码类型ID,超时时间(秒),识别结果
        cid, result = yundama.decode(filename, codetype, timeout);
        print('cid: %s, result: %s' % (cid, result))
    
    return result

login_url = "https://so.gushiwen.org/user/login.aspx?from=http://so.gushiwen.org/user/collect.aspx"
headers = {
    "Connection": "close",
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.80 Safari/537.36"
}

# 向登录页发送请求,解析出页面源码数据里面的登录参数值和验证码图片
page_text = requests.get(url=login_url, headers=headers).text
tree = etree.HTML(page_text)
view_state = tree.xpath('//form[@name="aspnetForm"]/div[1]/input/@value')[0]
view_state_generator = tree.xpath('//form[@name="aspnetForm"]/div[2]/input/@value')[0]
code_url = "https://so.gushiwen.org/" + tree.xpath('//img[@id="imgCode"]/@src')[0]

# 下载验证码图片并保存到本地
code_img_content = requests.get(url=code_url, headers=headers).content
with open('./img_code.jpg', 'wb') as f:
    f.write(code_img_content)

# 使用打码平台识别验证码
# code = input("请输入验证码: ")
code_text = get_code_text(1004, './img_code.jpg')
print(code_text)

# 封装请求参数,再发起模拟登录并访问用户主页,查看是否已经登录成功
login_post_url = "https://so.gushiwen.org/user/login.aspx?from=http%3a%2f%2fso.gushiwen.org%2fuser%2fcollect.aspx"
data = {
    "__VIEWSTATE": view_state,
    "__VIEWSTATEGENERATOR": view_state_generator,
    "from": "http://so.gushiwen.org/user/collect.aspx",
    "email": "username",
    "pwd": "password",
    "code": code_text,
    "denglu": "登录"
}
user_page_text = requests.post(url=login_post_url, headers=headers, data=data).text
with open('./gushiwen.html', 'w', encoding='utf-8') as fp:
    fp.write(user_page_text)
模拟登录古诗文网
# 人人网携带验证码的模拟登录
# 1.识别验证码
import time
import random
import requests
from lxml import etree
from urllib import request
from code_class import YDMHttp

requests = requests.Session()


def get_code_text(code_type, file_path):
    result = None

    # 普通用户名
    username = 'username'

    # 密码
    password = 'password'

    # 软件ID,开发者分成必要参数。登录开发者后台【我的软件】获得!
    appid = 7971

    # 软件密钥,开发者分成必要参数。登录开发者后台【我的软件】获得!
    appkey = 'b6fef487706d29041c20e6f9da220669'

    # 图片文件
    filename = file_path

    # 验证码类型,# 例:1004表示4位字母数字,不同类型收费不同。请准确填写,否则影响识别率。在此查询所有类型 http://www.yundama.com/price.html
    codetype = code_type

    # 超时时间,秒
    timeout = 30

    # 检查
    if (username == 'username'):
        print('请设置好相关参数再测试')
    else:
        # 初始化
        yundama = YDMHttp(username, password, appid, appkey)

        # 登陆云打码
        uid = yundama.login();
        print('uid: %s' % uid)

        # 查询余额
        balance = yundama.balance();
        print('balance: %s' % balance)

        # 开始识别,图片路径,验证码类型ID,超时时间(秒),识别结果
        cid, result = yundama.decode(filename, codetype, timeout);
        print('cid: %s, result: %s' % (cid, result))

    return result


def get_unique_timestamp():
    """
    获取人人网登录地址时间戳
    :return:
    """
    localtime = time.localtime()
    today = int(time.strftime("%w"))
    ran_num = random.randint(1000, 99999)
    unique_time_stamp = str(localtime[0]) + str(localtime[1] - 1) + str(today) + str(localtime[3]) + str(ran_num)

    return unique_time_stamp


url = "http://www.renren.com/"
headers = {
    "Connection": "close",
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.80 Safari/537.36"
}
page_text = requests.get(url=url, headers=headers).text

# 解析出验证码图片的地址
tree = etree.HTML(page_text)
img_url = tree.xpath('//*[@id="verifyPic_login"]/@src')[0]
print(img_url)
page_content = requests.get(url=img_url, headers=headers).content
with open('./img_code.jpg', 'wb') as f:
    f.write(page_content)

# 使用打码平台识别验证码
code_text = get_code_text(1006, './img_code.jpg')
print(code_text)
# code_text = input("请输入验证码: ")

# 获取登录动态码参数rkey
get_key_url = "http://login.renren.com/ajax/getEncryptKey"
data_json = requests.get(url=get_key_url, headers=headers).json()
print(data_json)  # {'isEncrypt': True, 'e': '10001', 'n': 'c98650a51a42c2522d67a37c13ae142be25821ac23074db8a8863114e22399f5', 'maxdigits': '19', 'rkey': '0452cd7fedabf16e84a21d42ee7b46d4'}
rkey = data_json['rkey']

# 模拟登录
login_url = "http://www.renren.com/ajaxLogin/login?1=1&uniqueTimestamp={}".format(get_unique_timestamp())
data = {
    "email": "email",
    "icode": code_text,
    "origURL": "http://www.renren.com/home",
    "domain": "renren.com",
    "key_id": "1",
    "captcha_type": "web_login",
    "password": "53ed186e58ff5426ded959d41ac86024c0e31a9fdd32dc762afa8bda262dc0b4",
    "rkey": rkey,
    "f": "http%3A%2F%2Fwww.renren.com%2FSysHome.do"
}
"""
现在遇到的问题是密码属于RSA动态加密的,解决方案可参考文档https://blog.csdn.net/livecoldsun/article/details/30067165
"""
response = requests.post(url=login_url, headers=headers, data=data)
print(response.json())
模拟登录人人网
import time
import random


def get_unique_timestamp():
    """
    获取人人网登录地址时间戳
    :return: 
    """
    localtime = time.localtime()
    today = int(time.strftime("%w"))
    ran_num = random.randint(1000, 99999)
    unique_time_stamp = str(localtime[0])+str(localtime[1]-1)+str(today)+str(localtime[3])+str(ran_num)

    return unique_time_stamp
解决人人网登录地址时间戳

 

posted @ 2019-06-14 08:36  tiger_li  阅读(686)  评论(1编辑  收藏  举报