欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

python爬虫实践之模拟登录

程序员文章站 2022-07-07 08:00:10
有些网站设置了权限,只有在登录了之后才能爬取网站的内容,如何模拟登录,目前的方法主要是利用cookie模拟登录。 浏览器访问服务器的过程 在用户访问网页时,不论是通过url...
有些网站设置了权限,只有在登录了之后才能爬取网站的内容,如何模拟登录,目前的方法主要是利用cookie模拟登录。

浏览器访问服务器的过程


在用户访问网页时,不论是通过url输入域名或ip,还是点击链接,浏览器向web服务器发出了一个http请求(http request),web服务器接收到客户端浏览器的请求之后,响应客户端的请求,发回相应的响应信息(http response),浏览器解析引擎,排版引擎分析返回的内容,呈现给用户。web应用程序在于服务器交互的过程中,http请求和响应时发送的都是一个消息结构。

python爬虫实践之模拟登录


http消息


当浏览器向服务器发送请求的时候,发出http请求消息报文,服务器返回数据时,发出http响应消息报文,这两种类型的消息都是由一个起始行,消息头,一个指示消息头结束的空行和可选的消息体组成。http请求消息中,起始行包括请求方法,请求的资源, http协议的版本号,消息头包含各种属性,消息体包含数据,get请求并没有消息主体,因此在消息头后的空白行中没有其他数据。http响应消息中,起始行包括http协议版本,http状态码和状态,消息头包含各种属性,消息体包含服务器返回的数据内容。
python爬虫实践之模拟登录

如下图从fiddler抓取的http请求和http响应,get请求内容为空,故消息头之后的空行和消息体都为空。
python爬虫实践之模拟登录

服务器发送的响应消息如下,浏览器正常接收到服务器发回的http报文 python爬虫实践之模拟登录
python爬虫实践之模拟登录

从上可以看到,cookie在http请求和http响应的头信息中,cookie是消息头的一种很重要的属性。

什么是cookie?

   当用户通过浏览器首次访问一个域名时,访问的web服务器会给客户端发送数据,以保持web服务器与客户端之间的状态保持,这些数据就是cookie,它是 internet 站点创建的 ,为了辨别用户身份而储存在用户本地终端上的数据,cookie中的信息一般都是经过加密的,cookie存在缓存中或者硬盘中,在硬盘中的是一些小文本文件,当你访问该网站时,就会读取对应网站的cookie信息,cookie有效地提升了我们的上网体验。一般而言,一旦将 cookie 保存在计算机上,则只有创建该 cookie 的网站才能读取它。
python爬虫实践之模拟登录

为什么需要cookie


http协议是一个无状态的面向连接的协议,http协议是基于tcp/ip协议层之上的协议,当客户端与服务器建立连接之后,它们之间的tcp连接一直都是保持的,至于保持的时间是多久,是通过服务器端来设置的,当客户端再一次访问该服务器时,会继续使用上一次建立的连接,但是,由于http协议是无状态的,web服务器并不知道这两个请求是否同一个客户端,这两次请求之间是独立的。 为了解决这个问题, web程序引入了cookie机制来维护状态.cookie可以记录用户的登录状态,通常web服务器会在用户登录成功后下发一个签名来标记session的有效性,这样免去了用户多次认证和登录网站。记录用户的访问状态。

cookie的种类


会话cookie(session cookie):这个类型的cookie只在会话期间内有效,保存在浏览器的缓存之中,用户访问网站时,会话cookie被创建,当关闭浏览器的时候,它会被浏览器删除。 持久cookie(persistent cookie): 这个类型的cookie长期在用户会话中生效。当你设置cookie的属性max-age为1个月的话,那么在这个月里每个相关url的http请求中都会带有这个cookie。所以它可以记录很多用户初始化或自定义化的信息,比如什么时候第一次登录及弱登录态等。 secure cookie:安全cookie是在https访问下的cookie形态,以确保cookie在从客户端传递到server的过程中始终加密的。 httponly cookie :这个类型的cookie只能在http(https)请求上传递,对客户端脚本语言无效,从而有效避免了跨站攻击。 第三方cookie: 第一方cookie是当前访问的域名或子域名下的生成的cookie。 第三方cookie:第三方cookie是第三方域名创建的cookie。

cookie的构成


cookie是http消息头中的一种属性,包括:cookie名字(name)cookie的值(value),cookie的过期时间(expires / max-age),cookie作用路径(path),cookie所在域名(domain),使用cookie进行安全连接(secure)。 前两个参数是cookie应用的必要条件,另外,还包括cookie大小(size,不同浏览器对cookie个数及大小限制是有差异的)。

python模拟登录


设置一个cookie处理对象,它负责 将cookie添加到http请求中,并能从http响应中得到cookie , 向网站登录页面发送一个请求request, 包括登录url,post请求的数据,http header 利用urllib2.urlopen发送请求,接收web服务器的response。 首先我们查看登陆页面源码
python爬虫实践之模拟登录

当我们使用urllib处理url的时候,实际上是通过urllib2.openerdirector实例进行工作,他会自己调用资源进行各种操作如通过协议、打开url、处理cookie等。而urlopen方法使用的是默认的opener来处理问题,基本的urlopen()函数不支持验证、cookie或其他的http高级功能。要支持这些功能,必须使用build_opener()函数来创建自己的自定义opener对象。
cookielib模块定义了自动处理http cookies的类,用来访问那些需要cookie数据的网站,cookielib模块包括cookiejar,filecookiejar,cookiepolicy,defaultcookiepolicy,cookie及filecookiejar的子类mozillacookiejar和lwpcookiejar,cookiejar对象可以管理http cookies,将cookie添加到http请求中,并能从http响应中得到cookie,filecookiejar对象主要是从文件中读取cookie或创建cookie,其中,mozillacookiejar是为了创建与mozilla浏览器cookies.txt兼容的filecookiejar实例,lwpcookiejar是为了创建与libwww-perl的set-cookie3文件格式兼容的filecookiejar实例,用lwpcookiejar保存的cookie文件易于人类阅读。默认的是filecookiejar没有save函数,而mozillacookiejar或lwpcookiejar都已经实现了。 所以可以用mozillacookiejar或lwpcookiejar,去自动实现cookie的save。
#! /usr/bin/env python
#coding:utf-8

import sys
import re
import urllib2
import urllib
import requests
import cookielib

## 这段代码是用于解决中文报错的问题  
reload(sys)  
sys.setdefaultencoding("utf8")  
#####################################################
#登录人人
loginurl = 'https://www.renren.com/plogin.do'
logindomain = 'renren.com'

class login(object):
    
    def __init__(self):
        self.name = ''
        self.passwprd = ''
        self.domain = ''

        self.cj = cookielib.lwpcookiejar()            
        self.opener = urllib2.build_opener(urllib2.httpcookieprocessor(self.cj)) 
        urllib2.install_opener(self.opener)    
    
    def setlogininfo(self,username,password,domain):
        '''设置用户登录信息'''
        self.name = username
        self.pwd = password
        self.domain = domain

    def login(self):
        '''登录网站'''
        loginparams = {'domain':self.domain,'email':self.name, 'password':self.pwd}
        headers = {'user-agent': 'mozilla/5.0 (windows nt 6.1) applewebkit/537.36 (khtml, like gecko) chrome/31.0.1650.57 safari/537.36'}
        req = urllib2.request(loginurl, urllib.urlencode(loginparams),headers=headers)  
        response = urllib2.urlopen(req)
        self.operate = self.opener.open(req)
        thepage = response.read()        
        
if __name__ == '__main__': 	 
	userlogin = login()
	username = 'username'
	password = 'password'
	domain = logindomain
	userlogin.setlogininfo(username,password,domain)
	userlogin.login()