Skip to content

代理IP

更新: 2025/2/24 字数: 0 字 时长: 0 分钟

在最开始讲到爬虫请求头的时候,就提到 User-Agent 是最重要的参数,这是因为许多服务器都会检测请求头的 User-Agent 参数是否是浏览器,因此我们要尽量将爬虫伪装成正常的用户使用浏览器来请求访问,来避免服务器的反爬检测。虽然我们尽力的将爬虫伪装成用户在使用浏览器浏览页面,但因为爬虫要不断的采集网页,因此爬虫向服务器发送 HTTP 请求的频率也会大大高于真实用户请求的频率,当网站服务器检测到这些 HTTP 请求来自同一个 IP 地址时,服务器会在一段时间内拒绝来自该 IP 地址的 HTTP 请求服务,并返回一些错误信息(403状态码 Forbidden,这种情况就称为封 IP,于是乎网站就成功把我们的爬虫禁掉了。

image-20240122163418145

针对这种封 IP 的反爬措施,有两种解决方案:

  • 方案一:增加爬取页面之间的延迟,降低网站的访问频率。
  • 方案二:既然服务器通过 IP 地址来封禁爬虫,那我们就准备多个 IP 地址来伪装爬虫,让服务器认为是由多台不同 IP 地址的客户端发起的 HTTP 请求,即通过不同的 IP 进行跳转访问,这样就可以的成功防止了 IP 地址被封,同时也突破了网站对一个 IP 地址设置的访问频率限制。

代理说明

基本原理

**代理,这里指的就是代理服务器,英文叫作 Proxy Server。功能是代网络用户取得网络信息。形象点说,代理是网络信息的中转站。当客户端正常请求一个网站时,是把请求发送给了 Web 服务器,Web 服务器再把响应传回给客户端。设置代理服务器,就是在客户端和服务器之间搭建一座桥,此时客户端并非直接向 Web 服务器发起请求,而是把请求发送给代理服务器,然后由代理服务器把请求发送给 Web 服务器,Web 服务器返回的响应也是由代理服务器转发绐客户端的。这样客户端冋样可以正常访问网页,而且这个过程中 Web 服务器识别出的真实 IP 就不再是客户端的 IP 了,成功实现了 IP 伪装,这就是代理的基本原理。**为了更好的理解代理,打个比方:某商场搞活动,一张券换一桶油,但是一个人只能换一次。A 有两张券,A 去换了一桶油,假如 A 第二次去换油必然遭到拒绝,这时 A 找到了 B,把券给了 B,让 B 去换油回来给 A,这样 A 就换到了两桶油,这时 B 就可以说是 A 的代理。简单说,代理就是代替他人执行某项请求。

主要功能

代理可以应用在很多方面,我们简单列举一下:

  • **突破自身 IP 的访问限制。**比如,访问一些单位或团体的内部资源,使用教育网内地址段的免费代理服务器,就可以下载和上传对教育网开放的各类 FTP,也可以查询、共享各类资料等。
  • **提高访问速度和下载速度。**通常,代理服务器会设置一个较大的硬盘缓冲区,当有外界的信息通过时,会同时将其保存到自己的缓冲区中,当其他用户访问相同的信息时,直接从缓冲区中取出信息,提高了访问速度。还例如,有些网站提供的下载资源做了一个 IP 一个线程的限制,这时候就可以使用代理 IP 突破下载速度限制。
  • 隐藏真实 IP。上网者可以通过代理隐藏自己的 IP,免受攻击。对于爬虫来说,由于爬取速度过快,因此在爬取过程中可能会遇到同一个 IP 访问过于频繁的问题,此时网站会让我们输入验证码登录或者直接封锁 IP,这样会给爬取造成极大的不便。使用代理隐藏真实的 IP,让服务器误以为是代理服务器在请求自己。这样在爬取过程中不断更换代理,就可以避免 IP 被封锁,达到很好的爬取效果。

20200411212749

代理分类

根据隐私分为:普通代理、匿名代理。

  • 普通代理:代理服务器通常会在客户端发送过来的请求的头部加上 HTTP_VIA HTTP_X_FORWARD_FOR 字段,使用这种代理是可能反向查到客户端的 IP。

  • 匿名代理:会将数据包原封不动转发,服务端记录的是代理服务器的 IP。

根据时间分为:短效代理、长效代理。

  • 短效代理:存活期在 1-2 分钟、3 分钟、5 分钟、10 分钟等的代理 IP。当然,不同时效定价也不同,时间越长,价格也越高。适用于 IP 使用频率高,代理 IP 数量大但时效短的业务场景,一般爬取网络数据的业务都会用到短效代理 IP。
  • 长效代理:存活时间比较长的 IP 地址,代理 IP 使用时长自由控制,灵活多变,可长期使用,可以最低 1-2 个小时切换一次。适用于 IP 使用频率低、时效长的业务场景。

根据费用分为:免费代理、付费代理。

  • 免费代理:可用 IP 数量少,且 IP 访问慢、不稳定、可用率低。比如快代理免费代理IP ,但是这些免费代理大多数情况下都是不好用的。

20230309142932

  • 付费代理:可用 IP 数量和付费价格相关,IP 访问快、稳定、可用率高(强烈建议在商用项目中使用付费代理)。

20200406200710

根据类型分为:拨号代理、蜂窝代理、私密代理、独享代理、海外代理、软件代理、隧道代理。

  • 拨号代理:用 ADSL 拨号更换 IP,拨一次号换一次 IP,稳定性高,是一种比较有效的封锁解决方案。

  • 蜂窝代理:用 4G 或 5G 网卡等制作的代理。由于用蜂窝网络作为代理的情形较少,因此整体被封锁的概率会较低,但搭建蜂窝代理的成本是较高的。

  • 私密代理:使用高品质 Http/Socks 代理服务器,满足动态和短效 IP 的使用需求,提供高速、可信赖的网络代理服务,需要手动管理 IP 池。非常适合对代理 IP 数量要求很大,对代理品质要求高的客户。

    • 按量付费:按 IP 的数量进行一次性付费,付费后给到 IP 提取数量,在订单有效期内 IP 都是可以提取,提取 IP 后开始计时(IP可用时长)并扣除相应的 IP 数量,当 IP 余数为 0 时,就不能再提取 IP,需要续费或重新购买。主要适用于时段内集中大量或少量使用 IP 的场景,或者不定期、不规律使用 IP 的场景。
    • 包年包月:购买包年包月产品后,每天可以使用固定的最大 IP 数量。不过对于不同 IP 有效时长(从提取到 IP 时算起,IP 可稳定使用的时长,超过这个时长 IP 会失效),每天可购买的最大 IP 量有所不同,使用有效时长越长的 IP,可提取的 IP 数量就越少。主要适用于每天持续运行需要固定量 IP 的业务。
  • 独享代理:基于优质云主机构建的高品质 Http/Socks 代理服务器,满足静态和长效 IP 的使用需求,具有极快的速度和极高的稳定性。主要面向长效 IP 使用场景,静态型具有一个固定 IP(非特殊情况不能更换),动态型 IP 每天更换 1 次,可根据业务需要的 IP 个数按需购买,通过 API 接口来获取代理 IP。非常适合对代理IP数量需求不大,但对稳定性和品质要求极高的场景。

  • 海外代理:来自中国香港/澳门/台湾和国外的代理 IP,可以访问全球 200 多个国家和地区的网页/应用。这时有人就想可不可以通过海外代理绕开一些访问限制,不过你能想到的空子,运营商早就已经想好对策了,所以运营商要求海外代理需在中国香港/澳门/台湾和国外网络环境下使用。海外代理主要满足对高成功率、天然防封、多样场景和全球转发的需求,适用于海外数据采集、跨境 / 海外电商、国际舆情监控等场景。

  • 软件代理:有的代理运营商会提供一个代理软件,软件在本地安装并启动后,会在本机的某个端口上创建 HTTP 或 SOCKS 代理服务,地址为 127.0.0.1:端口号,后面我们的请求只要设置了这个代理地址,就相当于和远程的代理服务器建立了一个 HTTP 隧道,它可以将本机的请求发送到代理软件连接的远程代理服务器,再由代理服务器进行转发。

  • 隧道代理:基于动态 IP 代理服务器,将换 IP 操作放到云端,这样用户无须通过 API 提取并更换代理 IP,也无须维护 IP 池,只需设置 1 个固定的隧道代理(高速 HTTP 隧道),用户每次发送的请求隧道代理会将其转发到不同的代理 IP 实现 IP 不断更换。因为在云端换 IP,如果转发的 IP 不可用,隧道代理会自动再转发到 1 个新的可用 IP,用户是无感知的。因此相比传统代理服务器,隧道代理使用更加简单,同时也极大的简化了编程的复杂度。适合对代理稳定性(7x24 小时连续使用)和品质要求高,希望代理自动切换 IP 的场景。

    • 并发限制:使用隧道代理时,需要控制好并发数,如果请求隧道的频率过高,很可能会被服务商判定为恶意请求。
    • 转发周期:可以在购买时指定隧道的换 IP 周期,既可以每次请求转发到 1 个新 IP,也可以每隔一段时间转发到 1 个新 IP。但对于通常需要同一个 IP 发出多次请求才能顺利拉回来页面,或者使用浏览器或程序模拟浏览器(headless browser,如 selenium,phantomjs 等)访问网页的场景,以及需要登录并保持登录状态的爬虫,不建议每次请求转发到新 IP。

隧道代理示意图

提醒

当我们在代理服务商那里购买了代理后,为了保证购买的代理只有我们自己的服务器才能使用,一定要设置 IP 白名单。一般的代理服务商都会提供 IP 白名单,通过在 IP 白名单中添加我们自己的服务器 IP,这样只有我们自己的 IP 地址才能连接并使用代理,除了我们服务器外的其他 IP 均不能使用我们购买的代理,哪怕知道我们的提取账号和密码,获取到了我们的付费代理 IP,也会因为发起连接代理服务器的本机 IP 地址不在白名单上而导致连接失败。

代理组成

**代理通常是以字典形式展现,键名是协议的类型,即 httphttps,键值是由协议、用户、密码、代理服务器的 IP 地址、端口号组成,当请求链接使用的是 HTTP 协议时,通过 http 键名对应的代理地址转发请求,当请求链接使用的是 HTTPS 协议时,使用 https 键名对应的代理地址转发请求。**例如下面的代理 IP:

python
{
    "http": "http://user:[email protected]:18782",
    "https": "http://user:[email protected]:18782"
}
  • http/https 协议类型(区分请求链接使用不同的协议走不同的代理);
  • http:// 协议类型(客户端向代理服务器发起请求所使用的协议,一般都是 http://);
  • user 用户名(用于付费代理的用户验证,若添加了 IP 白名单,则不需要);
  • pwd 密码(用于付费代理的用户验证,若添加了 IP 白名单,则不需要);
  • 110.242.134.206 代理服务器的 IP 地址;
  • 18782 代理服务器的端口号;

[!ATTENTION]

这里要注意的是,协议类型的 httpshttps 和代理地址的 http:// 是没有任何关系的。如果代理本身设置为使用 HTTP 协议,那么代理地址协议统一为 http://

代理池搭建

搭建代理池文章参考:IP代理池

不管是免费代理,还是付费代理,都不能保证每个代理都是 100% 可用的。比如某个代理 IP 被其他人拿来爬取同样的目标站点而被封禁,又或者代理服务器突然发生故障或网络繁忙,而我们选用了一个不可用的代理,这势必会影响爬虫的工作效率。**所以,需要提前筛选,将不可用的代理剔除掉,保留可用代理,搭建一个高效易用的代理的集合,这就是“代理池”。**其一般包含四个模块:

  • 获取模块: 负责在各大代理网站抓取代理。
  • 存储模块: 负责存储抓取下来的代理。
  • 检测模块: 负责定时检测数据库中的代理是否可用。
  • 接口模块: 负责用 API 来提供对外服务的接口。

处理流程:运行代理池,在各大代理网站抓取代理,可用代理分数设置为 100,不可用代理分数减 1。本机的代理池配置运行在 5000 端口,访问该端口随机获取一个可用代理。

image-20240122173818590

设置代理

浏览器代理

浏览器设置代理,可以使用一款名叫 SwitchyOmega 插件来设置 Chrome 浏览器的代理IP。此插件安装好后如图,可以看到它默认的模式是“直接连接”,也就是说浏览器不经过代理,直接通过本地 IP 进行访问:

20230602162306

现在我们访问一下 http://httpbin.org/get 这个网址,在“origin”可以看到发起请求的 IP 地址,这个地址我们的本机地址:

20230602164300

我们点击上图中插件的“选项”进入配置页面,在右侧“情景模式”中选择“proxy”选项,在“网址协议”中的 http://https:// 两行进行配置,它表示请求 http:// 协议的网址走哪个代理,请求 https:// 协议的网址走哪个代理。然后选择“代理协议”,这个就要根据代理 IP 给出的协议进行设置,通常都是 HTTP。最后就是配置“代理服务器”和“代理端口”了,这里为了演示效果,选择两个不同的代理和接口。配置完成后点击“应用选项”保存修改:

20230602163008

然后我们点击SwitchyOmega插件图标选择“proxy”,让我们前面配置的代理生效:

20230602164832

现在我们重新访问一下 http://httpbin.org/get 这个网址,可以看到发起请求的 IP 地址变成了我们所配置的代理IP。由于所请求的地址是 http 开头的,也就是该网址所使用的是 http:// 协议,因此就走的配置中 http:// 网址协议这行的代理 IP 地址。

20230602165121

现在我们访问一下 https://httpbin.org/get 这个网址,可以看到由于所请求的地址是 https 开头的,也就是该网址所使用的是 https:// 协议,因此就走的配置中 https:// 网址协议这行的代理 IP 地址。

20230602175042

需要注意的是,在 Chrome 浏览器无痕模式下是无法加载 SwitchyOmega 插件来设置代理的,因此访问上述两个网址返回的都是本机的 IP 地址,不过我们可以通过设置系统代理来解决。

20230602180052

系统代理

**系统代理,就是系统级别的代理,只要是从当前系统发出的请求,都会走该代理。**这里我们先在 SwitchyOmega 插件中选择“直接连接”模式,也就是说不设置浏览器代理:

20230602162306

点击 Chrome 浏览右上角的选项按钮,选择“设置”,在搜索框中搜索“代理”,点击“停用”,将 SwitchyOmega 插件停用掉:

20230602181501

停用后会出现“打开您计算机的代理设置”选项,我们点击该选项:

20230602181742

出现系统选项,我们点击手动设置代理中的”设置按钮“:

20230602181907

来到”编辑代理服务器“界面,打开代理服务器,在下方输入代理IP的地址以及端口号,最后点击”保存按钮“:

20230602182008

现在我们再来访问上面的两个网址,可以看到在 Chrome 无痕模式下,无论地址使用的 http:// 协议,还是 https:// 协议,其返回的都是系统设置的代理 IP 的地址。

20230602182155

爬虫代理

访问流程

**当我们给爬虫添加了一个代理 IP 之后,提供代理 IP 的服务器就会成为爬虫爬取过程中的一个中间平台。**其流程如下:

  1. 启动爬虫程序后,爬虫先访问连接代理 IP 的服务器地址;
  2. 与代理 IP 的服务器连接成功后,服务器转发爬虫携带的 HTTP 请求到达目标服务器;
  3. 目标服务器检查发起 HTTP 请求的 IP 地址,若不在限制IP名单上,对其返回正常响应;
  4. 代理 IP 的服务器接收到目标服务器的响应后,再将响应转发给爬虫。

上面的流程中,代理 IP 的服务器接替并完成了爬虫的 HTTP 请求,所以在服务器里的访问记录里留下就只是代理 IP 的地址,而不是爬虫本地的 IP 地址,但是也由于这个特性,在本地开启的抓包工具只能抓到爬虫和代理 IP 服务器之间传递的数据包,而与目标站点之间传递的数据包全在代理 IP 服务器上。

设置代理

**我们在代理运营商那里购买了代理之后,就可以通过 API 来提取并使用代理了,在requests 中设置代理的流程很简单,只需要构造代理字典,然后赋值给 proxies 参数即可。**代码如下:

python
import requests

# 通过API接口提取代理IP
api_url = "https://..."
proxy_ip = requests.get(api_url).text
# 方式一:用户名密码认证(私密代理/独享代理)
proxies = {
    "http": "http://%(user)s:%(pwd)s@%(proxy)s/" % {"user": "username", "pwd": "password", "proxy": proxy_ip},
    "https": "http://%(user)s:%(pwd)s@%(proxy)s/" % {"user": "username", "pwd": "password", "proxy": proxy_ip}
}
# 方式二:白名单方式(需提前设置白名单)
proxies = {
    "http": "http://%(proxy)s/" % {"proxy": proxy_ip},
    "https": "http://%(proxy)s/" % {"proxy": proxy_ip}
}
# 假如我们构造代理字典如下
proxies = {
    'http': 'http://117.139.208.10:9743',
    'https': 'http://117.139.208.10:9743'
}
# 添加到proxies代理参数中(请求http和https网页均适用)
url = 'http://httpbin.org/get'
response = requests.get(url=url, proxies=proxies)
print(response.text)
'''
输出:
{
  "args": {}, 
  "headers": {...}, 
  "origin": "117.139.208.10", 
  "url": "http://httpbin.org/get"
}
注释:origin显示的就是代理IP,而非本机IP,这证明代理已经设置成功了。
'''

同样的,在会话对象当中设置代理 IP 也很简单。代码如下:

python
import requests

# 创建一个会话对象
session = requests.session()
# 设置代理IP
session.proxies = {
    'http': 'http://113.194.141.162:8085', 
    'https': 'http://113.194.141.162:8085'
}

设置隧道

同样的,设置隧道代理也很简单,和上面几乎一模一样。代码如下:

python
import requests

# 隧道域名:端口号
tunnel = "XXX.XXX.com:15818"
# 方式一:用户名密码方式
proxies = {
    "http": "http://%(user)s:%(pwd)s@%(proxy)s/" % {"user": "username", "pwd": "password", "proxy": tunnel},
    "https": "http://%(user)s:%(pwd)s@%(proxy)s/" % {"user": "username", "pwd": "password", "proxy": tunnel}
}
# 方式二:白名单方式(需提前设置白名单)
proxies = {
    "http": "http://%(proxy)s/" % {"proxy": tunnel},
    "https": "http://%(proxy)s/" % {"proxy": tunnel}
}
# 要访问的目标网页
target_url = "https://..."
# 使用隧道域名发送请求
response = requests.get(target_url, proxies=proxies)

[!ATTENTION]

请求头中请勿使用 Connection: keep-alive 复用连接,否则会导致隧道不能切换 IP。

开发建议

爬虫在使用代理 IP 的时候,参考如下开发建议,以便顺利地完成开发和调试:

  1. IP 时效性,提取 IP 后尽快使用,不要在 IP 池里放太久;

  2. IP 高可用,随时调用 API 接口获取 IP 的剩余可用时长,淘汰掉不可用的 IP;

  3. 建立代理池,有人每次请求都会请求 API 服务器获取一个代理 IP 来发送请求,这样不仅会增加耗时请求,如果频率太快还会被 API 服务器封禁 IP。建议用户在本地程序中或者使用 Redis 维护一个代理 IP 池,避免 API 的高频调用;

  4. 控制好请求频率,用同一 IP 请求同一网站建议不超过 1 秒 1 次,避免 IP 被目标网站屏蔽;

  5. 采用 gzip 压缩加速访问,使用 gzip 压缩传输数据可显著提升访问速度,方法非常简单,在请求头中添加 Accept-Encoding: gzip 字段即可,收到响应后检查响应头里是否包含 Content-Encoding: gzip,如果包含,则对 body 进行 gzip 解压,就能得到原始内容。

  6. 建议关闭 HTTP 协议的 keep-alive 功能,平常我们在写爬虫的时候,请求头 Connection 字段默认都是 Connection: Keep-Alive,表示本地爬虫期望与服务器之间保持一段时间的 TCP 连接,这样写的好处就是,使用会话对象请求时,可以复用底层的 TCP 连接,在一次 TCP 连接基础上可以进行多次 HTTP 请求,避免每次 HTTP 请求都来进行”三次握手“建立 TCP 连接,减少资源浪费和等待时间,提高爬虫效率。但爬虫通过代理 IP 访问网站后,代理 IP 还会保持一段时间与该网站的 TCP 连接。若多个爬虫都在使用同一个代理 IP 访问不同的网站,那么代理 IP 就会与不同的网站建立 TCP 连接,然而代理 IP 能维持的 TCP 连接数量是有限制的,当连接数超过限制时,就会抛出 requests.exceptions.ConnectionError: HTTPSConnectionPool Max retries exceeded 错误,所以后面的爬虫使用该代理 IP 就无法与目标服务器建立 TCP 连接,也就无法发送 HTTP 请求。所以使用代理的爬虫需要在请求头中设置 Connection: Close 关闭 TCP 持久连接,这样可以确保在请求结束后及时释放代理服务器和目标服务器之间的 TCP 连接,如果使用的是会话对象,也可以通过 .close() 方法来关闭会话,释放 TCP 长连接,而不必依赖于 HTTP 头部设置。

建议

TCP 连接的保持时间不是固定的,而是由服务器和客户端的配置决定,可以根据实际需求进行调整。一些网站可能会选择较短的 TCP 连接保持时间,以确保服务器资源不会被长时间占用,同时允许更多的客户端建立连接。另一方面,一些网站可能会选择较长的连接保持时间,以减少建立和关闭连接的开销,提高性能。