Python web crawler notes (10) Cookies

Cookie refers to a text file stored on the user's browser by some website servers in order to identify the user's identity and perform session tracking. The cookie can keep the login information to the user's next session with the server.

Cookie principle

HTTP is a stateless connection-oriented protocol. In order to maintain the connection state, the Cookie mechanism is introduced. Cookie is an attribute in the HTTP message header, including:

Cookie名字(Name)
Cookie的值(Value)
Cookie的过期时间(Expires/Max-Age)
Cookie作用路径(Path)
Cookie所在域名(Domain),
使用Cookie进行安全连接(Secure)。

前两个参数是Cookie应用的必要条件,另外,还包括Cookie大小(Size,不同浏览器对Cookie个数及大小限制是有差异的)。

A cookie consists of a variable name and a value. According to Netscape's regulations, the cookie format is as follows:

Set-Cookie: NAME=VALUE;Expires=DATE;Path=PATH;Domain=DOMAIN_NAME;SECURE

Cookie application

The most typical application of cookies in crawling is to determine whether a registered user has logged in to the website, and the user may be prompted whether to retain the user information when entering the website next time to simplify the login procedure.

# 获取一个有登录信息的Cookie模拟登陆

import urllib.request

# 1. 构建一个已经登录过的用户的headers信息
headers = {
    "Host":"www.renren.com",
    "Connection":"keep-alive",
    "Upgrade-Insecure-Requests":"1",
    "User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36",
    "Accept":"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
    "Accept-Language":"zh-CN,zh;q=0.8,en;q=0.6",

    # 便于终端阅读,表示不支持压缩文件
    # Accept-Encoding: gzip, deflate, sdch,

    # 重点:这个Cookie是保存了密码无需重复登录的用户的Cookie,这个Cookie里记录了用户名,密码(通常经过RAS加密)
    "Cookie": "anonymid=ixrna3fysufnwv; depovince=GW; _r01_=1; JSESSIONID=abcmaDhEdqIlM7riy5iMv; jebe_key=f6fb270b-d06d-42e6-8b53-e67c3156aa7e%7Cc13c37f53bca9e1e7132d4b58ce00fa3%7C1484060607478%7C1%7C1484060607173; jebecookies=26fb58d1-cbe7-4fc3-a4ad-592233d1b42e|||||; ick_login=1f2b895d-34c7-4a1d-afb7-d84666fad409; _de=BF09EE3A28DED52E6B65F6A4705D973F1383380866D39FF5; p=99e54330ba9f910b02e6b08058f780479; ap=327550029; first_login_flag=1; [email protected]; ln_hurl=http://hdn.xnimg.cn/photos/hdn521/20140529/1055/h_main_9A3Z_e0c300019f6a195a.jpg; t=214ca9a28f70ca6aa0801404dda4f6789; societyguester=214ca9a28f70ca6aa0801404dda4f6789; id=327550029; xnsid=745033c5; ver=7.0; loginfrom=syshome"
}

# 2. 通过headers里的报头信息(主要是Cookie信息),构建Request对象
urllib.request.Request("http://www.renren.com/", headers = headers)

# 3. 直接访问renren主页,服务器会根据headers报头信息(主要是Cookie信息),判断这是一个已经登录的用户,并返回相应的页面
response = urllib.request.urlopen(request)

# 4. 打印响应内容
print (response.read().encode())

But this is too complicated. We first need to log in to the account in the browser, set and save the password, and obtain this cookie by capturing packets. Is there a simpler and more convenient way?

cookielib library and HTTPCookieProcessor processor

Handling cookies in Python3 is generally used together with the handler class of the http.cookiejar module and the urllib.request module .HTTPCookieProcessor

http.cookiejarModule: The main function is to provide an object for storing cookies

HTTPCookieProcessorHandler: The main function is to process these cookie objects and build a handler object.

http.cookiejar 库

The main objects of this module are CookieJar, FileCookieJar, MozillaCookieJar, LWPCookieJar.

  • CookieJar: An object that manages HTTP cookie values, stores cookies generated by HTTP requests, and adds cookies to outgoing HTTP requests. The entire cookie is stored in memory, and the cookie will also be lost after the CookieJar instance is garbage collected.

  • FileCookieJar (filename,delayload=None,policy=None):从CookieJar派生而来,用来创建FileCookieJar实例,检索cookie信息并将cookie存储到文件中。filename是存储cookie的文件名。delayload为True时支持延迟访问访问文件,即只有在需要时才读取文件或在文件中存储数据。

  • MozillaCookieJar (filename,delayload=None,policy=None):从FileCookieJar派生而来,创建与Mozilla浏览器 cookies.txt兼容的FileCookieJar实例。

  • LWPCookieJar (filename,delayload=None,policy=None):从FileCookieJar派生而来,创建与libwww-perl标准的 Set-Cookie3 文件格式兼容的FileCookieJar实例。

其实大多数情况下,我们只用CookieJar(),如果需要和本地文件交互,就用 MozillaCookjar() 或 LWPCookieJar()

我们来做几个案例:

1)获取Cookie,并保存到CookieJar()对象中
import urllib.request
import http.cookiejar

# 构建一个CookieJar对象实例来保存cookie
cookiejar = http.cookiejar.CookieJar()

# 使用HTTPCookieProcessor()来创建cookie处理器对象,参数为CookieJar()对象
handler=urllib.request.HTTPCookieProcessor(cookiejar)

# 通过 build_opener() 来构建opener
opener = urllib.request.build_opener(handler)

# 4. 以get方法访问页面,访问之后会自动保存cookie到cookiejar中
opener.open("http://www.baidu.com")

## 可以按标准格式将保存的Cookie打印出来
cookieStr = ""
for item in cookiejar:
    cookieStr = cookieStr + item.name + "=" + item.value + ";"

## 舍去最后一位的分号
print (cookieStr[:-1])

我们使用以上方法将Cookie保存到cookiejar对象中,然后打印出了cookie中的值,也就是访问百度首页的Cookie值。

运行结果如下:

BAIDUID=4327A58E63A92B73FF7A297FB3B2B4D0:FG=1;BIDUPSID=4327A58E63A92B73FF7A297FB3B2B4D0;H_PS_PSSID=1429_21115_17001_21454_21409_21554_21398;PSTM=1480815736;BDSVRTM=0;BD_HOME=0
2. 访问网站获得cookie,并把获得的cookie保存在cookie文件中
import http.cookiejar
import urllib.request

# 保存cookie的本地磁盘文件名
filename = 'cookie.txt'

# 声明一个MozillaCookieJar(有save实现)对象实例来保存cookie,之后写入文件
cookiejar = http.cookiejar.MozillaCookieJar(filename)

# 使用HTTPCookieProcessor()来创建cookie处理器对象,参数为CookieJar()对象
handler = urllib.request.HTTPCookieProcessor(cookiejar)

# 通过 build_opener() 来构建opener
opener = urllib.request.build_opener(handler)

# 创建一个请求,原理同urllib.request的urlopen
response = opener.open("http://www.baidu.com")

# 保存cookie到本地文件
cookiejar.save()
3. 从文件中获取cookies,做为请求的一部分去访问

import http.cookiejar
import urllib.request

# 创建MozillaCookieJar(有load实现)实例对象
cookiejar = http.cookiejar.MozillaCookieJar()

# 从文件中读取cookie内容到变量
cookie.load('cookie.txt')

# 使用HTTPCookieProcessor()来创建cookie处理器对象,参数为CookieJar()对象
handler = urllib.request.HTTPCookieProcessor(cookiejar)

# 通过 build_opener() 来构建opener
opener = urllib.request.build_opener(handler)

response = opener.open("http://www.baidu.com")

利用cookielib和post登录人人网

import urllib.request
import urllib.parse
import http.cookiejar

#通过类CookieJar类实例化一个对象,用来保存cookie的值
cookie = http.cookiejar.CookieJar()

#通过HTTPCookieProcessor处理器类构建一个处理器对象,用来处理cookie
#参数就是构建的CookieJar对象
cookie_handler = urllib.request.HTTPCookieProcessor(cookie)

#构建一个自定义的opener
opener = urllib.request.build_opener(cookie_handler)

#自定义opener的addheaders的参数,可以添加HTTP报头参数
opener.addheaders = [("User-Agent","Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36")]

#人人网登录接口
url = "http://www.renren.com/PLogin.do"

#需要登录的账户密码
data = {"email":"18763167932", "password":"linux2015"}

#通过urlencode()编码转换
data = urllib.parse.urlencode(data).encode(encoding='UTF8')

#构建一个post请求,发送登录所需要的参数,获取cookie
req = urllib.request.Request(url, data=data)

#发送post请求,如果登录成功生成cookie
response = opener.open(req)

print(response.read().decode())

#发送get请求,这个请求将保存生成cookie一并发到web服务器,服务器会验证cookie通过
response_deng = opener.open("http://www.renren.com/812144683/profile")

#获取登陆后才能访问的页面
print(response_deng.read().decode())

模拟登录要注意几点:

  1. 登录一般都会先有一个HTTP GET,用于拉取一些信息及获得Cookie,然后再HTTP POST登录。
  2. HTTP POST登录的链接有可能是动态的,从GET返回的信息中获取。
  3. password 有些是明文发送,有些是加密后发送。有些网站甚至采用动态加密的,同时包括了很多其他数据的加密信息,只能通过查看JS源码获得加密算法,再去破解加密,非常困难。
  4. 大多数网站的登录整体流程是类似的,可能有些细节不一样,所以不能保证其他网站登录成功。
这个测试案例中,为了想让大家快速理解知识点,我们使用的人人网登录接口是人人网改版前的隐藏接口(嘘....),登录比较方便。
当然,我们也可以直接发送账号密码到登录界面模拟登录,但是当网页采用JavaScript动态技术以后,想封锁基于 HttpClient 的模拟登录就太容易了,甚至可以根据你的鼠标活动的特征准确地判断出是不是真人在操作。
所以,想做通用的模拟登录还得选别的技术,比如用内置浏览器引擎的爬虫(关键词:Selenium ,PhantomJS),这个我们将在以后会学习到。


Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324893349&siteId=291194637