scrapy手工识别验证码登录超星泛雅

我这两天一直都在学习scrapy如何保持会话状态,在网上找了好多的资料以及博主的文章,做了一点总结。这里,以超星网课登录系统作为例子讲解:

1. 第一步肯定是找到登录时需要提交的post表单数据,最快的办法就是查看页面源代码或者F12找出对应的form表单里面的action,如果查看的action是空值,也就是js加载的,我们则需要在网络中找出对应的提交链接请求。

经过登录测试和分析,登录的url为“https://passport2.chaoxing.com/login”,并且请求方法为post,也就是我们在登录的时候需要通过FormRequest发送而不是普通的Request方法(如果使用的是requests库的话,需要通过post而不是普通的get方法)

2. 第二步则是最重要的,找到或者分析出验证码对应的url链接,所以我们需要通过F12点击元素以及网络中的请求来找出生成验证码对应的url链接。

经过分析发现,每次刷新验证码或者网页都会重新生成一个url链接,也就是 code?一串数字 ,经分析发现 验证码对应的url为: img_url = "https://passport2.chaoxing.com/num/code?"+str(int(time.time()))

并且发现,对应于同一个验证码url,刷新之后都会出现不同的验证码图片。这个问题困惑了我整整一天,也是解决这次爬虫的关键:  由于对于同一个验证码url每请求一次对应的验证码都会变化一次,当我们在爬虫的时候,肯定首先要请求验证码图片对应的url来加载到本地,最后人工识别验证码后 填补到 form的post表单对应的一项中最后再整体提交给 登录的url链接。!!!! 但是,这是两次请求,无论是请求登录的url还是验证码的url 验证码的图片都会改变!!! 所以我们要做的就是,如何保持 让自己下载到本地的验证码 和 登录请求时 更新的验证码 保持一致,那么就引出了scrapy提供的cookiejar机制来保持会话状态:

(1)meta={'cookiejar':1}    表示开启cookie记录,首次请求时写在Request()里
(2)meta={'cookiejar':response.meta['cookiejar']}    表示使用上一次response的cookie,
(3)meta={'cookiejar':True}    表示使用授权后的cookie访问需要登录查看的页

下面直接上代码吧,这里只展示scrapy的spider核心文件:

# scrapy模拟登录 超星泛雅
# 手动输入验证码

# -*- coding: utf-8 -*-
import scrapy
from urllib import request
from PIL import Image
from base64 import b64encode
import requests
from requests import session
import time
import re
from scrapy.http.cookies import CookieJar
from scrapy.http import Request,FormRequest

class WljxptSpider(scrapy.Spider):
    name = 'wljxpt'
    # allowed_domains = ['passport2.chaoxing.com']
    start_urls = ['https://passport2.chaoxing.com/login']
    # 登录url,其实和 start_urls是一样的,只不过,一个是列表,一个是字符串
    login_url = start_urls[0]

    headers = {
        'Upgrade-Insecure-Requests': '1',
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36',
        'Connection': 'keep-alive'
    }

    def start_requests(self):
        return [Request(self.start_urls[0], callback=self.parse)]

    def parse(self, response):
        # 拼凑当前验证码对应的 url
        num = int(time.time())
        img_url = "https://passport2.chaoxing.com/num/code?"+str(num)
        yield scrapy.Request(url=img_url, meta={'cookiejar': 1}, callback=self.parse_postdata)

    def parse_postdata(self, response):

        print("正在登录...................")
        form_data = {
            'refer_0x001': 'http%3A%2F%2Fi.mooc.chaoxing.com%2Fspace%2Findex.shtml',
            'pid': '-1',
            'pidName': '',
            'fid': '-1',
            'fidName': '',
            'allowJoin': '0',
            'isCheckNumCode': '1',
            'f': '0',
            'uname': '',  # 输入自己的账号
            'password': '',   # 输入自己的密码
            'numcode': '',
        }

        # 保存验证码图片 并且自动打开后 人工输入验证码
        fp = open('验证码.png', 'wb')
        fp.write(response.body)
        fp.close()

        image = Image.open('验证码.png')
        image.show()
        captcha = input("请输入验证码: ")
        # 完善 formdata中空着的 numcode
        form_data['numcode'] = captcha

        #return [FormRequest.from_response(response, url=self.login_url, meta={'cookiejar': response.meta['cookiejar']}, headers=self.headers, formdata=form_data, callback=self.parse_afterlogin)]
        yield scrapy.FormRequest(url=self.login_url, meta={'cookiejar': response.meta['cookiejar']}, headers=self.headers, formdata=form_data, callback=self.parse_afterlogin)


    # 登录后继续使用该cookie信息去访问登录后才能访问的页面,就不会被拦截到登录页面了
    def parse_afterlogin(self, response):
        # 访问登陆后才能访问的页面http://i.mooc.chaoxing.com/settings/info?t=1594542872701
        yield Request("http://i.mooc.chaoxing.com/settings/info", meta={'cookiejar': True}, callback=self.parse_manager)


    # 保存文件
    def parse_manager(self, response):
        with open("用户管理.html", "w", encoding='utf-8') as fp:
            fp.write(response.text)

 

  • 2
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值