爬虫入门_5:requests模块高级使用及案例实战

模拟登录

模拟登录:爬取基于某些用户的用户信息。

cookie

cookie:用来让服务器端记录客户端的相关状态。

  • 手动处理:通过抓包工具获取cookie值,将该值封装到headers中(不建议)

  • 自动处理:

    • cookie值的来源在哪里?

      • 模拟登录post请求后,由服务器端创建
    • session会话对象:

      • 作用:可以进行请求的发送

        如果请求过程中产生了cookie,则该cookie会被自动存储/携带在该session对象中

    • 创建一个session对象:session=requests.Session()

    • 使用session对象进行模拟登录post请求的发送(cookie就会被存储在session对象中)

    • session对象对个人主页对应的get请求进行发送(携带了cookie)

实战

需求1:对古诗文网进行模拟登录
流程:
  • 点击登录按钮之后会发起一个post请求

  • post请求中会携带登录之前录入的相关登录信息(用户名,密码,验证码…)

  • 验证码:每次请求都会变化

代码

编码流程:

  1. 验证码的识别,获取验证码图片的文字数据
  2. 对post请求进行发送(处理请求参数)
  3. 对响应数据进行持久化存储

以下是代码的实现,其中验证码识别代码(VerificationCode),点这里

import requests
from lxml import etree
from VerificationCode import VerificationCode


def getCodeText(imgPath):
    """
    封装识别验证码图片的函数
    :param imgPath:验证码图片路径
    :return: 返回识别的验证码文本
    """
    a = VerificationCode(imgPath)
    result = a.image_str()
    return result

if __name__ == '__main__':
    # UA伪装,相关的头信息封装在字典结构中
    headers = {
        "User-Agent": 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.82 Safari/537.36'
    }
    # 创建一个session对象,该对象会自动将请求中的cookie进行存储和携带
    session = requests.session()
    # 对验证码图片进行捕获和识别
    url = 'https://so.gushiwen.cn/user/login.aspx?from=http://so.gushiwen.cn/user/collect.aspx'
    response = session.get(url=url,headers=headers)
    response.encoding = 'utf-8'  # 将编码设置为‘utf-8',不然会出现乱码
    page_text = response.text
    tree = etree.HTML(page_text)
    # 保存html
    with open('./result/gushiwen.html','w',encoding='utf-8') as fp:
        fp.write(page_text)
    # 判断是否为验证码的页面,如果是,进行验证码识别、模拟登录
    title = tree.xpath('//*[@id="aspnetForm"]/div[4]/div[4]/span/text()')
    print(title)
    if '验证码' in title:
        print("登录存在验证码,需要进行验证码识别!!")
        code_img_src = tree.xpath('//*[@id="imgCode"]/@src')[0]
        code_img_url = 'https://so.gushiwen.cn/' + code_img_src
        print(code_img_url)

        code_img_data = session.get(url=code_img_url, headers=headers).content
        with open('./result/code_gsw.jpg','wb') as fp:
            fp.write(code_img_data)
        print("图片保存成功!!")

        # 调用OCR图片识别代码进行验证码图片数据识别,识别率不太高
        print("图片识别中....")
        code_text = getCodeText('./result/code_gsw.jpg')

        if code_text == '' or code_text == None:
            print("未识别成功!!!")
        else:
            print("识别结果为:", code_text)

            # post请求的发送(模拟登录)
            login_url = 'https://so.gushiwen.cn/user/login.aspx?from=http%3a%2f%2fso.gushiwen.cn%2fuser%2fcollect.aspx'
            data = {
                '__VIEWSTATE': 'J4lKFTZmKFCNCqJLPTrKQ/7J32z28jdpXU8l41kXfvKh60kKv5eXR9PdfNwW06f2mPSDL61OATQFdEPf+8JbjiVsqiHnrBSw7mA38Rn+n+r73+7pYhtlKr7i6UU=',
                '__VIEWSTATEGENERATOR': 'C93BE1AE',
                'from': 'http://so.gushiwen.cn/user/collect.aspx',
                'email': '用户名',
                'pwd': '密码',
                'code': code_text,
                'denglu': '登录'
            }
            response = session.post(url=login_url, headers=headers, data=data)

            # 判断是否登录成功
            if response.status_code == 200:
                print("模拟登录成功!!!")
            else:
                print("模拟登录失败!!!")

运行代码后,结果如下:
在这里插入图片描述

需求2:爬取古诗文网当前用户的我的背诵页数据
  • http/https协议特性:无状态
  • 没有请求到对应页面数据的原因:发起的第二次基于个人主页页面请求的时候,服务器端并不知道该次请求是基于登录状态下的请求
代码
import requests
from lxml import etree
from VerificationCode import VerificationCode

def getCodeText(imgPath):
    """
    封装识别验证码图片的函数
    :param imgPath:验证码图片路径
    :return: 返回识别的验证码文本
    """
    a = VerificationCode(imgPath)
    result = a.image_str()
    return result


if __name__ == '__main__':
    # UA伪装,相关的头信息封装在字典结构中
    headers = {
        "User-Agent": 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.82 Safari/537.36'
    }
    # 创建一个session对象,该对象会自动将请求中的cookie进行存储和携带
    session = requests.session()
    # 对验证码图片进行捕获和识别
    url = 'https://so.gushiwen.cn/user/login.aspx?from=http://so.gushiwen.cn/user/collect.aspx'
    response = session.get(url=url, headers=headers)
    response.encoding = 'utf-8'  # 将编码设置为‘utf-8',不然会出现乱码
    page_text = response.text
    tree = etree.HTML(page_text)
    # 保存html
    with open('./result/gushiwen.html', 'w', encoding='utf-8') as fp:
        fp.write(page_text)
    # 判断是否为验证码的页面,如果是,进行验证码识别、模拟登录
    title = tree.xpath('//*[@id="aspnetForm"]/div[4]/div[4]/span/text()')

    if '验证码' in title:
        print("登录存在验证码,需要进行验证码识别!!")
        code_img_src = tree.xpath('//*[@id="imgCode"]/@src')[0]
        code_img_url = 'https://so.gushiwen.cn/' + code_img_src
        print("验证码的url地址: ",code_img_url)

        code_img_data = session.get(url=code_img_url, headers=headers).content
        with open('./result/code_gsw.jpg', 'wb') as fp:
            fp.write(code_img_data)
        print("图片保存成功!!")

        # 调用OCR图片识别代码进行验证码图片数据识别,识别率不太高
        print("图片识别中....")
        code_text = getCodeText('./result/code_gsw.jpg')

        if code_text == '' or code_text == None:
            print("未识别成功!!!")
        else:
            print("识别结果为:", code_text)

            # post请求的发送(模拟登录)
            login_url = 'https://so.gushiwen.cn/user/login.aspx?from=http%3a%2f%2fso.gushiwen.cn%2fuser%2fcollect.aspx'
            data = {
                '__VIEWSTATE': 'J4lKFTZmKFCNCqJLPTrKQ/7J32z28jdpXU8l41kXfvKh60kKv5eXR9PdfNwW06f2mPSDL61OATQFdEPf+8JbjiVsqiHnrBSw7mA38Rn+n+r73+7pYhtlKr7i6UU=',
                '__VIEWSTATEGENERATOR': 'C93BE1AE',
                'from': 'http://so.gushiwen.cn/user/collect.aspx',
                'email': '用户名称',
                'pwd': '密码',
                'code': code_text,
                'denglu': '登录'
            }
            # 使用session进行post请求的发送
            response = session.post(url=login_url, headers=headers, data=data)

            # 判断是否登录成功
            if response.status_code == 200:
                print("模拟登录成功!!!")
            else:
                print("模拟登录失败!!!")

            login_page_text = response.text
            # 持久化存储
            with open('./result/gushiwen.html', 'w', encoding='utf-8') as fp:
                fp.write(login_page_text)

            # 爬取当前用户的个人主页对应的页面数据
            detail_url = 'https://so.gushiwen.cn/user/collectbei.aspx?sort=t'

            # 使用携带cookie的session进行get请求的发送
            detail_page_text = session.get(url=detail_url, headers=headers).text
            with open('./result/user_page.html', 'w', encoding='utf-8') as fp:
                fp.write(detail_page_text)

运行结果如下:

在这里插入图片描述

代理

具体实战代码地址,点这里

如果本文对你有帮助,记得“点赞、收藏”哦~

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值