赞
踩
Requests高级
这篇文档中将介绍 Requests 的一些高级特性。为了模拟浏览器的功能,只有之前的知识是不够的,在学习了高级的知识后,我们可以更好的模拟浏览器的功能。完成更多的网页的采集工作。
HTTP协议是无状态的协议。无状态是指协议对于事务处理没有记忆功能。缺少状态意味着,假如后面的处理需要前面的信息,则前面的信息必须重传,这样可能导致每次连接传送的数据量增大。
另一方面,在服务器不需要前面信息时,应答就较快。直观地说,就是每个请求都是独立的,与前面的请求和后面的请求都是没有直接联系的。因此,Cookie和Session存在的作用是进行状态管理。会话对象让你能够跨请求保持某些参数。
Cookie,有时也用其复数形式 Cookies。类型为“小型文本文件”,是某些网站为了辨别用户身份,进行Session跟踪而储存在用户本地终端上的数据(通常经过加密),由用户客户端计算机暂时或永久保存的信息 [1] 。——百度百科
现在的网站中有这样的一种网站类型,也就是需要用户注册以后,并且登陆才能访问的网站,或者说在不登录的情况下不能访问自己的私有数据,例如微博,微信等。
网站记录用户信息的方式就是通过客户端的Cookie值。例如:当我们在浏览器中保存账号和密码的同时,浏览器在我们的电脑上保存了我们的用户信息,并且在下次访问这个页面的时候就会自动的为我们加载Cookie信息。
在需要登陆的网站中,浏览器将Cookie中的信息发送出去,服务器验证Cookie信息,确认登录。既然浏览器在发送请求的时候带有Cookie信息,那么我们的程序同样也要携带Cookie信息。
Cookie是当你访问某个站点或者特定页面的时候,留存在电脑里的一段文本,它用于跟踪记录网站访问者的相关数据信息,比如:搜索偏好、行为点击,账号,密码等内容。
浏览器访问WEB服务器的过程
在用户访问网页时,不论是通过URL输入域名或IP,还是点击链接,浏览器向WEB服务器发出了一个HTTP请求(Http Request),WEB服务器接收到客户端浏览器的请求之后,响应客户端的请求,发回相应的响应信息(Http Response),浏览器解析引擎,排版引擎分析返回的内容,呈现给用户。WEB应用程序在于服务器交互的过程中,HTTP请求和响应时发送的都是一个消息结构
什么是 cookie
cookie在http请求和http响应的头信息中,cookie是消息头的一种很重要的属性. 当用户通过浏览器首次访问一个域名时,访问的WEB服务器会给客户端发送数据,以保持WEB服务器与客户端之间的状态保持,这些数据就是Cookie,它是 Internet 站点创建的 ,为了辨别用户身份而储存在用户本地终端上的数据,Cookie中的信息一般都是经过加密的,Cookie存在缓存中或者硬盘中,在硬盘中的是一些小文本文件,当你访问该网站时,就会读取对应网站的Cookie信息,Cookie有效地提升了我们的上网体验。一般而言,一旦将 Cookie 保存在计算机上,则只有创建该 Cookie 的网站才能读取它。
**为什么需要 cookie **
Http协议是一个无状态的面向连接的协议,Http协议是基于tcp/ip协议层之上的协议,当客户端与服务器建立连接之后,它们之间的TCP连接一直都是保持的,至于保持的时间是多久,是通过服务器端来设置的,当客户端再一次访问该服务器时,会继续使用上一次建立的连接,但是,由于Http协议是无状态的,WEB服务器并不知道这两个请求是否同一个客户端,这两次请求之间是独立的。 为了解决这个问题, Web程序引入了Cookie机制来维护状态.cookie可以记录用户的登录状态,通常web服务器会在用户登录成功后下发一个签名来标记session的有效性,这样免去了用户多次认证和登录网站。记录用户的访问状态。
比如说有些网站需要登录后才能访问某个页面,在登录之前,你想抓取某个页面内容是不允许的,那么我们可以利用Urllib2库保存我们登录的Cookie,然后再抓取其他页面就达到目的了。
**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个数及大小限制是有差异的)。
通常Cookie值信息可以在浏览器中复制过来,放到headers中:
import requests
headers = {
'Host': 'www.guazi.com',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4128.3 Safari/537.36',
'Cookie': 'uuid=ba1cebdd-0909-4b5d-b50c-225823c65563; cityDomain=cs; ganji_uuid=7928681736388097027029; Hm_lvt_936a6d5df3f3d309bda39e92da3dd52f=1586330277; cainfo=%7B%22ca_a%22%3A%22-%22%2C%22ca_b%22%3A%22-%22%2C%22ca_s%22%3A%22seo_baidu%22%2C%22ca_n%22%3A%22default%22%2C%22ca_medium%22%3A%22-%22%2C%22ca_term%22%3A%22-%22%2C%22ca_content%22%3A%22-%22%2C%22ca_campaign%22%3A%22-%22%2C%22ca_kw%22%3A%22-%22%2C%22ca_i%22%3A%22-%22%2C%22scode%22%3A%22-%22%2C%22keyword%22%3A%22-%22%2C%22ca_keywordid%22%3A%22-%22%2C%22display_finance_flag%22%3A%22-%22%2C%22platform%22%3A%221%22%2C%22version%22%3A1%2C%22client_ab%22%3A%22-%22%2C%22guid%22%3A%22ba1cebdd-0909-4b5d-b50c-225823c65563%22%2C%22ca_city%22%3A%22cs%22%2C%22sessionid%22%3A%220b4cc851-54e7-4f89-9967-7f27f4cd7773%22%7D; preTime=%7B%22last%22%3A1586330502%2C%22this%22%3A1586330275%2C%22pre%22%3A1586330275%7D; antipas=5k47N362080n2308V63z41314M'
}
response = requests.get('https://www.guazi.com/cs/20e17311773b1706x.htm', headers=headers)
response.encoding = response.apparent_encoding
print(response.text)
这样就可以随着请求头一起发送出去。当然requests也提供了cookies 参数,供我们提交Cookie信息:
import requests
url = xxx
cookies = {'Cookie': '你的Cookie值'}
r = requests.get(url, cookies=cookies)
注意事项:
现代的浏览器都已经有了维持会话这种功能,可以想象一下这样的场景:一个用户在浏览器中登陆了自己的账号,这样他就可以浏览主页了,但是该用户还想浏览该网站的其他页面,如果浏览器没有维持这次会话,那么用户访问该域名下的其他页面是就需要重复登陆。这显然比较麻烦。为了解决这样的问题,需要实现跨请求。
Session:在计算机中,尤其是在网络应用中,称为“会话控制”。Session对象存储特定用户会话所需的属性及配置信息。这样,当用户在应用程序的Web页之间跳转时,存储在Session对象中的变量将不会丢失,而是在整个用户会话中一直存在下去。当用户请求来自应用程序的 Web页时,如果该用户还没有会话,则Web服务器将自动创建一个 Session对象。当会话过期或被放弃后,服务器将终止该会话。其实维持会话的目的就是共享不同页面的Cookie。
''' 维持会话 ''' import requests # 设置Cookie的网址 url_set_cookie = 'http://httpbin.org/cookies/set/sessioncookie/123456789' # 获取Cookie的网址 url_get_cookie = 'http://httpbin.org/cookies' # 维持会话实例化 session = requests.Session() # 发送请求设置Cookie response_set_cookie = session.get(url_set_cookie) # 发送请求得到Cookie response_get_cookie = session.get(url_get_cookie) # 打印获取的Cookie值 print(response_get_cookie.text)
结果是:
{
"cookies": {
"sessioncookie": "123456789"
}
}
结果显示,在两次无关的请求中维持了相同的Cookie,也就是实现了共享Cookie值。
注意:
就算使用了会话,方法级别的参数也不会被跨请求保持。下面的例子只会和第一个请求发送Cookie,而非第二个:
'''
维持会话
'''
import requests
# 获取Cookie的网址
url_get_cookie = 'http://httpbin.org/cookies'
# 维持会话实例化
session = requests.Session()
# 发送请求得到Cookie
response_get_cookie = session.get(url_get_cookie, cookies={'form-my': 'scrapy@qq.com'})
# 打印获取的Cookie值
print(response_get_cookie.text)
# 再次请求不会维持参数级别的值
r = session.get(url_get_cookie)
print(r.text)
结果是:
{
"cookies": {
"form-my": "scrapy@qq.com"
}
}
################################################
{
"cookies": {}
}
# https://creditcard.ecitic.com/citiccard/ucweb/toRegister.do?sid=ECCQGS010 import requests import time from PIL import Image def get_time(): """获取时间戳""" """ 时间戳是指格林威治时间1970年01月01日00时00分00秒(北京时间1970年01月01日08时00分00秒)起至现在的总毫秒数。 秒级时间戳,10位 毫秒级时间戳,13位 微秒级时间戳,16位 """ now_time = str(int(time.time() * 1000)) # 获取当前时间的时间戳 print('当前时间的时间戳为:', now_time) return now_time session = requests.Session() # 准备请求参数 headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.29 Safari/537.36', } time_one = get_time() # 图片验证码的url地址 img_url = 'https://creditcard.ecitic.com/citiccard/ucweb/newvalicode.do?time=' + time_one response = session.get(img_url) img_data = response.content with open('yzm.jpg', mode='wb') as f: f.write(img_data) # 手动输入验证码 image = Image.open('yzm.jpg') image.show() code = input('请输入验证码:') print('输入的验证码为:', code) data = { 'phone': '18889898989', # 电话号码 'imgValidCode': code, # 验证码 } # 准备第二次请求的时间戳 time_two = get_time() # 获取短信验证码请求 code_url = 'https://creditcard.ecitic.com/citiccard/ucweb/getsms.do?×tamp{}' + time_two response_2 = session.post(code_url, data=data) print(response_2.json())
注意:
令牌、指纹、唯一无二的数据
有时候是一个加密参数
每一次请求, 都会生成一个新的 token
具体的生成规则,看具体的网站
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。