request模块高级操作
cookie&代理概述
- cookie
- 代理机制
cookie
- 是存储在客户端的一组键值对。
- web中cookie的典型应用:免密登录。
- cookie和爬虫之间的关联 sometimes,对页面进行请求的时候,如果请求的过程中不携带cookie,那么将无法请求到正确的页面数据。因此cookie是爬虫中一个非常典型且常见的反爬机制。
需求:爬取雪球网中首页推荐版块下标题和描述。url:https://xueqiu.com/
分析:
- 判断爬取的咨询数据是否是动态加载 。相关的更多咨询数据是动态加载的,滚轮滑动到底部的时候会动态加载出更多咨询数据。
- 定位到ajax请求的数据包,提取出请求的url,响应数据为json形式的咨询数据。
直接写报错:
{'error_description': '遇到错误,请刷新页面或者重新登录帐号后再试', 'error_uri': '/statuses/hot/listV2.json', 'error_data': None, 'error_code': '400016'}
问题: 没有请求到想要的数据,没有严格意义上模拟浏览器发请求。
处理:将浏览器发请求携带的请求,全部放在headers字典中,将headers作用到request的请求操作。重点关注cookie。
cookie的处理方式
方式1:手动处理 : 将抓包工具中的cookie粘贴在headers中,弊端cookie有效时长、动态变化后该方式失效处理方式。
方式2:自动处理 :基于Session对象实现自动处理。如何获取一个session对象:requests.Session()返回一个session对象。
session对象的作用:该对象和requests一样调用get和post方法发送指定HTTP请求,在使用session发请求的过程中,若产生了cookie则cookie会被自动存储到该session对象中,那么就意味着下次再次使用session对象发起请求,则该次请求就是携带cookie进行的请求发送。
在爬虫中使用session的时候,session对象至少会被使用几次?2次,第一次使用session是为了将cookie捕获且存储到session对象中。下次使用的时候携带cooke进行的请求发送。
自动处理cookie
#!/usr/bin/env python # -*- coding: utf-8 -*- # author: 青城子 # datetime: 2021/7/17 11:30 # ide: PyCharm import requests url = "https://xueqiu.com/statuses/hot/listV2.json?since_id=-1&max_id=229524&size=15" headers = { "User-Agent": 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.105 Safari/537.36', } session = requests.Session() # 创建好了session对象 # 第一次使用session捕获且存储cookie,猜测对雪球网的首页发起的请求可能会产生cookie main_url = "https://xueqiu.com/" session.get(main_url, headers=headers) # 捕获且存储cookie page_text = session.get(url=url, headers=headers).json() # 携带cookie发起请求 print(page_text)
代理操作
在爬虫中,所谓的代理指的是什么?就是代理服务器。
代理服务器的作用是什么?就是用来转发请求和响应。
在爬虫中为什么需要使用代理服务器?如果爬虫在短时间内对服务器高频的请求,那么服务器会检测到这样异常行为的请求,就会该请求对应设备的IP禁止。
如果IP被禁,可以使用代理服务器进行请求转发,破解IP被禁的反爬机制。
代理服务器分为不同的匿名度:
- 透明代理 :如果使用了该形式的代理,服务端知道你使用了代理机制也知道你的真实ip
- 匿名代理:知道你使用代理,但是不知道你的真实ip
- 高匿代理:不知道你使用了代理也不知道你的真实ip
代理类型
- http:转发http的请求
- https:代理只能转发https协议的请求
代理服务器(付费)
- 快代理
- 西祠代理
- 智连HTTP(常用)https://www.zhiliandaili.cn/
实例
多次访问西刺网站,让网站封我们IP,然后通过代理访问
#!/usr/bin/env python # -*- coding: utf-8 -*- # author: 青城子 # datetime: 2021/7/17 14:29 # ide: PyCharm import requests import random from lxml import etree headers = { "User-Agent": 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.105 Safari/537.36', } url = "" # 代理服务商提供的获取代理IP的API page_text = requests.get(url, headers=headers) tree = etree.HTML(page_text) proxy_list = tree.xpath("//body//text()") # 获取代理商提供的代理IP和端口,然后保存到代理池中 http_proxy = [] # 封装的代理池 for proxy in proxy_list: dic = { "https": proxy } http_proxy.append(dic) print(http_proxy) """ [ {"http":"58.243.28.218:33503"}, {"http":"114.106.151.234:10566"}, ] """ # 对西刺代理发起一个高频请求,让其将我本机ip禁掉 # url模板 new_url = "https://www.xicidaili.com/nn/%d" ips = [] for page in range(1, 11): new_url = format(url % page) # 让当次的请求使用代理机制,就可以更换请求的ip地址 page_text = requests.get(url=new_url, headers=headers, proxies=random.choice(http_proxy)).text tree = etree.HTML(page_text) # 在xpath表达式中不可以出现tbody标签 tr_list = tree.xpath("//*[@id='ip_list']//tr")[1:] for tr in tr_list: ip = tr.xpath("./td[2]/text()")[0] ips.append(ip) print(len(ips)) # 使用代理机制破解ip被封的效果