爬虫Day12-代理请求

前言

我们在爬虫的过程中会遇到一些反爬手段,例如封IP、封用户账号等行为,我们可以通过使用代理IP或者代理池进行代理访问,预防被反爬。如何学会代理请求是爬虫工程师必须会的技能噢~ 必须点满


代理的原理

我们常称呼的代理实际上指的就是代理服务器,英文叫做 ProxyServer,它的功能是代理网络用户去取得网络信息。也就是说,我们发送请求给代理服务器,再由他再次发出请求给服务端。这样就成功实现了 IP 伪装,也是代理的基本原理。

代理服务器这种机制,还有其他功能:

  • 隐藏真实IP,对于爬虫来说,我们用代理就是为了隐藏自身 IP,防止自身的 IP 被封锁。
  • 提高访问速度,通常代理服务器都设置一个较大的硬盘缓冲区,当有外界的信息通过时,同时也将其保存到缓冲区中,当其他用户再访问相同的信息时, 则直接由缓冲区中取出信息,传给用户,以提高访问速度。

Session和Cookies

接着,我们应该了解这两个概念:Session和Cookies。

在浏览网站的过程中我们经常会遇到需要登录的情况,有些页面只有登录之后我们才可以访问,而且登录之后可以连续访问很多次网站,但是有时候过一段时间就会需要重新登录。还有一些网站有时在我们打开浏览器的时候就自动登录了,而且很长的时间都不会失效,这种情况又是为什么?其实这里面涉及到 Session 和 Cookies 的相关知识


无状态HTTP

HTTP的无状态是指 HTTP协议对事务处理是没有记忆能力的,也就是说服务器不知道客户端是什么状态。当我们向服务器发送一个 Requset后,服务器解析此 Request,然后返回对应的 Response,服务器负责完成这个过程,而且这个过程是完全独立的,服务器不会记录前后状态的变化。(这就导致了如果用户后续需要对已经发送的数据再做操作就会导致重传等等一些浪费资源的现象)

所以,这时候,两个用于保持HTTP 连接状态的技术就出现了,它们分别是 Session 和Cookies。(Session在服务端,也就是网站的服务器,用来保存用户的会话信息,Cookies 在客户端,也可以理解为浏览器端)


Cookie的作用

有了 Cookies,浏览器在下次访问网页时会自动附带上它发送给服务器,服务器通过识别 Cookies 并鉴定出是哪个用户,然后再判断用户是否是登录状态,然后返回对应的 Response。Cookie相当于一个凭证的东西,有了它,就可以完成“身份检验”。

注意,Cookie 是由服务器端通过 set-Cookie字段发送给客户端的,而不是客户端自动产生的。


Session原理

在 Web 中 Session对象用来存储特定用户会话所需的属性及配置信息。当用户在应用程序的 Web 页之间跳转时,存储在Session 对象中的变量也不会丢失,会在整个用户会话中一直存在下去。(在登陆之后访问同网页下其他页面不需要重新登陆的原因)

当客户端再次访问时,服务器就拿着客户端携带的Cookies参数,检查该 Cookies 即可找到对应的Session是什么,然后再判断 Session来以此来辨认用户状态。这样,就实现了免登陆的效果。



神秘数字403

当运行的爬虫速率太高,或者被检测出你是个爬虫工具发出的访问时,网页可能会弹出这样的403警告信息:“您的 IP 访问频率太高”。出现这样的现象的原因是网站采取了一些反爬虫的措施,比如服务器会检测某个 IP 在单位时间内的请求次数,如果超过了这个阈值,那么会直接拒绝服务,返回一些错误信息。

例如,这样的写的爬虫…

1
2
3
4
import requests

for i in range(10000):
requests.get('http://www.baidu.com')

是不是想人家服务器挂掉…

别人不封你封谁,估计掐死你的心都有了,哈哈



爬虫代理的实现

requests的实现

1
2
3
4
5
6
7
8
9
10
11
12
13
import requests
proxy = '123.114.203.61:8118' # 代理IP + 端口号
proxies = {
'http':'http://' + proxy,
'https:':'https://' + proxy
}

try:
response = requests.get('http://httpbin.org/get', proxies =proxies)
# 代理需要通过 proxies 关键字指定,不然会以为是个data
print(response.text)
except requests.exceptions.ConnectionError as e:
print('ERROR',e.args)
  • proxy 变量接收的是我从网上找的免费代理,然后通过 IP +端口号的形式传给 get方法中的 proxies 变量,达到代理的效果
  • 这么设置之后,访问页面时,对端服务器看到的就是我们设置的这个IP发出的请求。如果被封了,我们可以通过更换IP进行修改

selenium的实现

1
2
3
4
5
6
7
8
9
from selenium import  webdriver

proxy = '123.114.203.61:8118'

chrome_options = webdriver.ChromeOptions()
chrome_options.add_argument('--proxy-server=http://' + proxy )
browser = webdriver.Chrome(chrome_options=chrome_options)
browser.get('http://httpbin.org/get')
print(browser.page_source)
  • selenium的实现是通过实例化一个带参数的 ChromeOptions 对象,然后这个对象就携带着我们添加进去的参数

后记

实现代理的途径还有代理池、付费代理、ADSL拨号等等,不过原理都是相似的,都是拿到一个IP,然后传给 请求函数,这样携带的请求就是代理 IP。

不过最好还是控制一下记己,服务器挂了大家都没得玩。利用爬虫的时间,冲冲茶养养生还是蛮不错的,哈哈哈