python爬虫之模拟登录

python爬虫之模拟登录

1.验证码识别

1.1 验证码和爬虫之间的联系?

验证码属于门户网站的一种反爬机制。若需使用爬虫来进行网站爬取数据的同时,需要识别验证码,则需先识别验证码图片中的数据,用于模拟登录操作。

1.2 识别验证码的操作

(1)人工肉眼识别。简而言之,就是事先将需爬取网站所需要识别的图片验证码下载下来,或先通过浏览器打开需爬取网站页面,识别获取图片验证码数据。不推荐此类方法,效率低且不适用于图片复杂图较高的验证码识别。

(2)第三方自动识别。通过借助于第三方线上平台(这些平台可以制定相关图片验证的操作和机制),帮助我们识别某些数据类型的验证码中的相关数据。推荐使用。 如:超级鹰验证码识别-专业的验证码云端识别服务,让验证码识别更快速、更准确、更强大 (chaojiying.com)

1.3 超级鹰的使用流程

(1)注册:普通用户和开发者用户

(2)登录

  • 普通用户的登录:查询该用户是否还有剩余的题分
  • 开发者用户的登录:
    • 创建一个软件:用户中心 —》软件ID —》生成一个ID(soft_id) —》录入软件名称 —》提交(软件ID和密钥)
    • 下载示例代码:开发文档 --》 超级鹰图像识别python语言demo下载 --》点击这里下载 —》运行时登录创建的用户账号,扣除用户积分进行图像识别,一次识别扣除10积分

实战案例:识别古诗文网登录页面中的验证码。

# 分析:使用超级鹰平台识别验证码的编码流程:
#      1.将验证码图片进行本地下载
#      2.调用平台提供的示例代码进行图片数据识别

import requests
from lxml import etree
import os
import chaojiying
if __name__ == "__main__":
    # 指定古诗文网站的url
    url = "https://so.gushiwen.cn/user/login.aspx?from=http://so.gushiwen.cn/user/collect.aspx"
    headers = {
        'User-Agent': ''
    }
    # 进行古诗文网站的页面爬取,获得页面数据
    page_text = requests.get(url=url,headers=headers).text
    # 对古诗文网站源码数据进行解析,获取验证码数据
    tree = etree.HTML(page_text)
    img_url = "https://so.gushiwen.cn" + tree.xpath('//img[@id="imgCode"]/@src')[0]
    print(img_url)
    # 获取验证码图片,并将其保存至本地
    img_data = requests.get(url=img_url,headers=headers).content
    img_name = "验证码.jpg"
    # 图片保存路径
    # if not os.path.exists:
    #     os.mkdir('../../data/验证码识别/')
    img_path = "../../data/验证码识别/" + img_name
    with open(img_path,'wb') as fp:
        fp.write(img_data)
        print(img_name,'下载成功!!!')
    # 识别验证码数据并返回
    code_data = chaojiying.Chaojiying_Client(username='账户名',password='密码',soft_id='9007').Recongination(file_name='../../data/验证码识别/验证码.jpg')['pic_str']
    print(code_data)

在这里插入图片描述

2.模拟登录

2.1 登录本质

网页上以及app中输入账号密码的过程称为登录不经过登录有些页面是无法直接跳转的。而模拟登录就是模拟手动输入账号密码的过程,获得登录成功后的cookie,以此cookie直接访问需要登录才能进入的页面(例如用户个人信息页面),从而获取数据。

2.2 什么是模拟登录?

模拟登录就是通过程序发送post请求某个应用网站的登录地址获取登录cookie信息。

2.3为什么需要模拟登录?

有些网站的信息**需要用户登录之后方可获取,故需要模拟用户登录,以便爬取基于某些用户的用户信息。**

2.4 模拟登录的目的

爬取基于某些用户的用户网站信息。

2.5 案例

(1)对古诗文网进行模拟登录

  • 分析:
    • 点击登录按钮之后会发起一个post请求
    • post请求中会携带登录之前录入的相关的登录信息(用户名,密码,验证码…)
    • 验证码具有的特点:每次发起请求,验证码都会动态改变,需重点分析
  • 代码如下:
# 编码流程:
# 1.验证码的识别:获取验证码图片的文字数据
# 2.对post请求进行发送(处理请求参数)
# 3.对响应数据进行持久化存储

import requests
from lxml import etree
from chaojiying_Python import chaojiying
if __name__ == "__main__":
    # 1.验证码的识别
    # 1.1 获取验证码的图片数据
    url = "https://so.gushiwen.cn/user/login.aspx?from=http://so.gushiwen.cn/user/collect.aspx"
    headers = {
        'User-Agent': ''
    }
    page_text = requests.get(url=url,headers=headers).text
    tree = etree.HTML(page_text)
    img_url = "https://so.gushiwen.cn" + tree.xpath('//img[@id="imgCode"]/@src')[0]
    img_data = requests.get(url=img_url,headers=headers).content
    img_path = '../data/test_1.jpg'
    with open(img_path,'wb') as fp:
        fp.write(img_data)
        print('验证码保存成功!!!')
    # 1.2 识别验证码数据
    code_data = chaojiying.Chaojiying_Client(username='账户名',password='密码',soft_id='9007').Recongination(file_name='../data/test_1.jpg')['pic_str']

    # 2.对post请求进行发送
    login_url = "https://so.gushiwen.cn/user/login.aspx"
    data = {
    "__VIEWSTATE":"mvj4doUURZ6yq81juT7sT8WEIM7xs2N19W58taJhJIorP6ZE9lkAgFaAMERbLe8AEZqnptvYKGHI9AJEqqLfGYO++5HIfPY/00dwpTOmRdeclaN337FNaDaE6xQh4goBbGubTbTixa+18xBIrwSMH6igDLU=",
    "__VIEWSTATEGENERATOR":"C93BE1AE",
    "from":"http://so.gushiwen.cn/user/collect.aspx",
    "email":"",  # 账户名
    "pwd":"",    # 密码
    "code":code_data,
    "denglu":"登录"
    }
    response = requests.post(url=login_url,headers=headers,data=data)
    if response.status_code == 200:
        login_page_text = response.text
        with open('gushiwen.html','w',encoding='utf-8') as fp:
            fp.write(login_page_text)
            print('登录成功!')
    else:
        print('登陆失败')

在这里插入图片描述

(2)模拟古诗网用户登录,并获取用户收藏数据

此案例中涉及到的问题:

(1)无法请求到对应页面数据(用户个人中心)

  • 形成原因:
    • 发起的第二次基于个人主页页面请求的时候,服务器端并不知道该次请求是基于登录状态下的请求。
    • 核心原因:服务器会根据请求中的cookie值来判断用户是否在登录状态,若是,才会显示与用户数据对应的用户主页;反之,则会显示没有携带用户数据的页面。
    • http与https协议的特点:并不会保存客户端发起请求的用户状态信息,即若只是通过url进行页面数据跳转,则用户状态信息默认为未登录
    • 注意:若只是单纯的通过requests库对用户的个人中心界面发起请求,会导致触发网站的登录锁(即网站会通过获取网页端的cookie进行用户登录状态判断,若并未登录用户,则不会显示用户数据的个人中心界面。
  • 解决办法:通过获取用户登录的cookie数据,发送第二次请求时携带用户登录的cookie数据
  • cookie的作用:用来让服务器端记录客户端的相关状态。
  • cookie值的来源:客户端或爬虫模拟登录发起post请求后,由服务器端创建。在客户端发起登录请求后,服务器端会对该请求的响应头设置**set-cookie**,其对应的便是cookie值。
  • 设置cookie的方法:
    • (1)手动处理:通过抓包工具获取cookie值,将该值封装到headers中。(不建议使用这种方法。理由如下)

      • cookie具有一定**时效性,若使用cookie超过一定时间,cookie会失效;其次,某些网站里的cookie具有动态性,即每发起一次请求,对应的cookie值会相应发生改变,通用性不高**。
    • (2)自动处理:通过使用session对象进行模拟登录post请求的发送

      • session:在计算机中,尤其是在网络应用中,称为“会话控制”。

      • Session对象的特性:session对象会存储特定用户会话所需的属性及配置信息。

      • session的作用:

        • 存储用户的相关状态信息,直到此次会话结束(一个会话就是一个请求,若用户在选择关闭浏览器后,对应的session会被销毁)。即若在*请求过程中产生了cookie*,则**该cookie会被自动存储或携带在该session对象中**。
        • 可以进行请求的发送。
      • 注意:一个Session的概念需要包括特定的客户端,特定的服务器端以及不中断的操作时间。A用户和C服务器建立连接时所处的Session同B用户和C服务器建立连接时所处的Session是两个不同的Session

      • session的来源:当用户请求来自应用程序的 Web页时,如果该用户还没有会话,则Web服务器将自动创建一个 Session对象。当会话过期或被放弃后,服务器将终止该会话。Session 对象最常见的一个用法就是存储用户的首选项。

      • 自动处理实现流程:

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

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

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

# 流程分析:
# 1.验证码的识别:获取验证码图片的文字数据
# 2.对post请求进行发送(处理请求参数)
# 3.对响应数据进行持久化存储
# 4.进入用户个人中心界面
# 5.解析用户个人中心界面数据,获取用户个人信息数据
# 注意:此案例并未成功获取到用户个人数据
# 没有请求到对应页面数据的原因:
# 发起的第二次基于个人主页页面请求的时候,服务器端并不知道该次请求是基于登录状态下的请求。
if __name__ == "__main__":
    # 1.验证码的识别
    # 1.1 获取验证码的图片数据
    url = "https://so.gushiwen.cn/user/login.aspx?from=http://so.gushiwen.cn/user/collect.aspx"
    headers = {
        'User-Agent': ''
    }
    page_text = requests.get(url=url,headers=headers).text
    tree = etree.HTML(page_text)
    img_url = "https://so.gushiwen.cn" + tree.xpath('//img[@id="imgCode"]/@src')[0]
    img_data = requests.get(url=img_url,headers=headers).content
    img_path = '../data/验证码识别/test_1.jpg'
    with open(img_path,'wb') as fp:
        fp.write(img_data)
        print('验证码保存成功!!!')
    # 1.2 识别验证码数据
    code_data = chaojiying.Chaojiying_Client(username='超级鹰账户',password='超级鹰账户密码',soft_id='07').Recongination(file_name='../data/test.jpg')['pic_str']

    # 2.对post请求进行发送
    login_url = "https://so.gushiwen.cn/user/login.aspx"
    data = {
    "__VIEWSTATE":"mvj4doUURZ6yq81juT7sT8WEIM7xs2N19W58taJhJIorP6ZE9lkAgFaAMERbLe8AEZqnptvYKGHI9AJEqqLfGYO++5HIfPY/00dwpTOmRdeclaN337FNaDaE6xQh4goBbGubTbTixa+18xBIrwSMH6igDLU=",
    "__VIEWSTATEGENERATOR":"C93BE1AE",
    "from":"http://so.gushiwen.cn/user/collect.aspx",
    "email":"", #古诗文账户
    "pwd":"", #古诗文密码
    "code": code_data,
    "denglu":"登录"
    }
    print('验证码识别为:',code_data)
    # 创建session对象
    session = requests.Session()
    # 使用session对象发起用户模拟登录请求
    response = session.post(url=login_url,headers=headers,data=data)
    if response.status_code == 200:
        login_page_text = response.text
        with open('登录后界面.html','w',encoding='utf-8') as fp:
            fp.write(login_page_text)
        print('登录成功!')
        # 对我的个人中心页面进行数据分析,获取我的收藏中的诗文数据
        # index_tree = etree.HTML(login_page_text)
        # college_url = "https://so.gushiwen.cn" + index_tree.xpath('//div[@class="son1"]/a[6]/@href')[0]
        # print(college_url)
        # 进入到我的个人中心页面
        # 编码流程分析:用户登录---》 进入用户端的首页  ---》 进入我的页面 ---》 点击诗词 ---》 获取到我的关于诗词的收藏的数据
        # 注意,若无法进入到用户主页,需使用携带cookie的session对象进行请求发送,服务器会根据cookie值判断用户是否登录
        college_url = 'https://so.gushiwen.cn/user/collect.aspx?type=s&id=4380460&sort=t'
        response = session.get(url=college_url,headers=headers)
        response.encoding = response.apparent_encoding
        content_page_text = response.text
        with open("我的个人中心界面.html",'w',encoding='utf-8') as fp:
            fp.write(content_page_text)
        content_page_tree = etree.HTML(content_page_text)
        # 解析获取我的收藏中诗词数据
        div_list = content_page_tree.xpath('//div[@class="sons"]/div[@class="cont"]')
        print(div_list)
        for div in div_list:
            content_text = div.xpath('./a/text()')
            print("我的收藏词句为:",content_text)
    else:
        print('登陆失败')

注意:以上代码并未成功获取到对应用户的收藏数据,并未进入到用户个人中心界面
在这里插入图片描述

3.代理

3.1 代理初始

大多数网站都有反爬虫机制,若同一时间段内同一个IP发送的请求次数过多超过了爬取网站定义的请求次数阈值,服务器会拒绝此IP发起的请求,并直接禁封该IP

此时,通过设置代理便可解决此类问题

什么是代理?

代理,即代理服务器的简称。其功能是代理网络用户,获取相关的网络信息。可以将代理服务器理解为建立在用户客户端和服务器端之间的桥梁,用户客户端发起请求会先将其请求发送至代理服务器中,而后再由代理服务器向对应的服务器发送客户端的请求,服务器响应给客户端的数据会先经过代理服务器处理后,在将其处理后的数据发送至用户客户端。

即,发送请求:客户端 ----》 代理服务器 —》服务器;

​ 响应数据:服务器 —》代理服务器 —》 客户端

注意,在此过程中,web服务器识别出的真实的IP地址并不是用户客户端的真实的IP了,因为经过了代理服务器的IP处理。

代理的作用

(1)突破自身IP访问的限制

(2)隐藏自身真实IP

代理相关网站

快代理、西刺代理、米扑代理等

代理IP的类型
  • http: 应用到http协议对应的url中
  • https: 应用到https协议对应的url中
代理ip的匿名度
  • 透明:服务器知道该次请求使用了代理,也知道请求对应的真实ip
  • 匿名:服务器知道此次请求使用了代理,但是不知道客户端的真实IP
  • 高匿:服务器不知道此次请求使用了代理,更不知道客户端的真实IP

练习:

# 需求:使用代理服务器发起请求,并验证IP与代理IP
import requests

if __name__ == '__main__':
    url = "http://www.baidu.com/s?wd=ip"
    headers = {
        'User-Agent': ''
    }
    # 使用免费的代理服务器,proxies为指定的代理服务器,其值为字典类型,http为代理服务器中对应的网络协议为http协议,
    # 91.241.39.118表示代理服务器的ip,8080表示该代理服务器的端口号
    page_text = requests.get(url=url,headers=headers,proxies={'HTTP':'91.241.39.118:8080'}).text
    with open('ip_w.html','w',encoding='utf-8') as fp:
        fp.write(page_text)
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值