Python爬虫学习(五)----requests模块高级

模拟登陆

引入

有时候,相关的需求会让我们去爬取基于某些用户的相关用户信息,例如爬取张三人人网账户中的个人身份信息、好友账号信息等。那么这个时候,我们就需要对当前用户进行登录操作,登录成功后爬取其用户的相关用户信息。

通过案例分析

需求:对慕课网进行模拟登录
分析:
- 点击登录后会发送一个post请求
- post请求会携带登录之前录入的登录信息(用户名、密码、验证码....)
编码流程
1.  验证码识别,获得验证码的文字数据。
2.  对post请求进行发送(处理其扭曲参数)。
3.  对响应数据进行持久化存储。

CodeClass.py:

from hashlib import md5
import requests


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

import requests
from lxml import etree
from CodeClass import Chaojiying_Client

if __name__ == "__main__":
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.129 Safari/537.36',
    }
    url = 'https://www.imooc.com/'
    page_text = requests.get(url=url, headers=headers).text
    
    tree = etree.HTML(page_text)
    # print(tree.xpath('//img[@class="verify-img"]/@src'))
    code_src = 'https://www.imooc.com' + tree.xpath('//*[@id="signup-form"]/div[3]/a[1]/img/@src')[0]
    code_data = requests.get(url=code_src, headers=headers).content

    with open('./code.jpg', 'wb') as fp:
        fp.write(code_data)
        print('验证码图片保存成功!')

    chaojiying = Chaojiying_Client('超级鹰普通用户用户名', '超级鹰普通用户密码', '创建的软件ID')
    # 本地图片文件路径 来替换 a.jpg 有时WIN系统须要//
    im = open('./code.jpg', 'rb').read()
    # 1902 验证码类型  官方网站>>价格体系 3.4+版 print 后要加()
    result = chaojiying.PostPic(im, 1902)
    code = result['pic_str']

    post_url = 'https://www.imooc.com/passport/user/login'
    data = {
        'username': '18895365005',
        'password': 'JRzyJBaM5K6WjwtoUFBxhdDEaT1M5YnJHj4lGemaTYndqs8DyB4hOy9BnkRgGLtNmswYQnm8cDB+omagyIwWBEn+8tqiJ5h96axlSNBRZujAsl3r3pu9TGMHQzTucQr0htrt84MTfLkNw5K9YH1i4Hs6Rz8+cQR2TzsVNRzFeJw=',
        'verify': code,
        'remember': 0,
        'pwencode': 1,
        'browser_key': '5677005aec336858c242e0e6417cdc16',
        'referer': 'https: // www.imooc.com'
    }
    response = requests.post(url=post_url, headers=headers, data=data)
    print(response.status_code)

requests模块的cookie处理

http/https协议特性:无状态

HTTP的无状态指的是http协议对事物处理是没有记忆能力的,也就是说服务器不知道客户端是什么状态。当我们向服务器发送请求后,服务器解析此请求,然后返回对应的响应,服务器负责完成这个过程,而且这个过程是完全独立的,服务器不会记录前后状态的变化,也就是缺少状态记录。这就意味着如果后续需要处理前面的信息,则必须重传,这导致需要额外传递一些前面的重复请求,才能获取后续响应,然而这种效果显然不是我们想要的。为了保持前后状态,我们肯定不能将前面的请求全部重传一次,这太浪费资源了,对于这种需要用户登录页面来说,更是棘手。

这时两个保持http连接状态的技术出现了,分别是会话cookie。会话在服务端,用来保存用户的会话信息。cookie在客户端,有了cookie,浏览器在下次访问网页时会自动附带上cookie发送给服务器,服务器识别cookie并鉴定出是哪个用户,然后在判断出用户的相关状态,然后返回对应的响应。

会话:会话(对象)是用来存储特定用户进行会话所需的属性及配置信息的。

cookie:指的是某些网站为了辨别用户身份、进行会话跟踪而存储在用户本地终端上的数据。

会话维持:当客户端第一次请求服务器时,服务器会返回一个响应对象,响应头中带有Set-Cookie字段,cookie会被客户端进行存储,该字段表明服务器已经为该客户端用户创建了一个会话对象,用来存储该用户的相关属性机器配置信息。当浏览器下一次再请求该网站时,浏览器会把cookie放到请求头中一起提交给服务器,cookie中携带了对应会话的ID信息,服务器会检查该cookie即可找到对应的会话是什么,然后再判断会话来以此辨别用户状态。

requests模块处理cookie的两种方式

方式一(手动处理):通过抓包工具获取cookie值,将该值封装到headers中

将cookie手动从抓包工具中获取,然后封装到requests请求的headers中,将headers作用到请求方法中。(不建议)

headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.129 Safari/537.36',
        'cookie':'XXX'
    }
方式二(自动处理):创建session会话对象,使用session会话对象进行请求发送。因为会话中会自动携带且处理cookie。(推荐)

session会话对象 作用:

- 可以进行请求的发送
- 如果请求中产生了cookie,则该cookie值会自动存储/携带在该session对象中。

创建session对象:

session = requests.Session()

在使用会话对象发起登陆请求时,需要额外注意该请求参数:

’authenticity_token':'lGnVdPaEf/jfBd6dzkQFpd4idQZxO96HSvRzWIPo5099dvmZTqEx+Q13zLjQzYpE08YmZdJStHd+Vk6Yhz7t/Q==
案例实战

需求:使用requests模块实现Gitee的模拟登录,并爬取用户首页信息。

import requests
from lxml import etree

if __name__ == "__main__":
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.129 Safari/537.36',
    }
    url = 'https://gitee.com/login'

    session = requests.Session()
    page_text = session.get(url=url, headers=headers).text

    tree = etree.HTML(page_text)
    t = tree.xpath('//*[@id="new_user"]/div[1]/input[2]/@value')[0]

    data = {
        'encrypt_key': 'password',
        'utf8': '✓',
        'authenticity_token': t,
        'redirect_to_url':'',
        'user[login]': 'wmyzzz',
        'encrypt_data[user[password]]': 'xxxxxx',
        'user[remember_me]': 0,
    }
    detail_page_text = session.post(url=url, headers=headers, data=data).text

    with open('./gitee.html', 'w', encoding='utf-8') as fp:
        fp.write(detail_page_text)
        print("爬取成功!")

requests模块的代理IP操作

反爬机制:封ip
反反爬策略:使用代理进行请求发送

引入

我们在做爬虫的过程中经常会遇到这样的情况,最初爬虫正常运行,正常抓取数据,一切看起来都是那么美好,然而一杯茶的功夫可能就会出现错误,比如403,这时打开网页一看,可能会看到“您的IP访问频率太高”这样的提示。出现这种现象的原因是网站采取了一些反爬措施。比如,服务器会检测某个IP在单位时间内请求的次数,如果超过了某个阈值,就会直接拒绝服务,返回一些错误信息,这种情况可以称为封IP。

既然服务器检测的是某个IP单位时间的请求次数,那么借助某种方式来伪装我们的IP,让服务器识别不出是由我们本机发起的请求,不就可以成功防止封IP了吗?一种有效的方式就是使用代理。

什么是代理?

代理指的就是代理服务器,它的功能就是代理网络用户去取得网络信息。形象的说,它是网络信息的中转站。在我们正常请求一个网站时,是发送了请求给Web服务器,Web服务器把响应传回我们。如果设置了代理服务器,实际上就是在本机和服务器之间搭建了一个桥梁,此时本机不是直接向Web服务器发起请求,而是向代理服务器发出请求,请求会发送给代理服务器,然后代理服务器再发送给Web服务器,接着由代理服务器再把Web服务器返回的响应转发给本机。这样我们同样可以正常访问网页,但这个过程中Web服务器识别出的真实IP就不再是我们本机的IP了,就成功实现了IP伪装,这就是代理的基本原理。

代理的作用

- 1.突破自身IP访问的限制,访问一些平时不能访问的站点。
- 2.隐藏真实IP,免受攻击,防止自身IP被封锁

代理相关的网站

- 快代理
- www.goubanjia.com

代理ip的匿名度

- 透明:服务器知道本次请求使用了代理,也知道请求对应的真实ip
- 匿名:知道使用了代理,不知道真实ip
- 高匿:不知道使用了代理,也不知真实ip
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值