Python构建免费爬虫代理池实战:从抓取到验证

Ada
Ada
发布时间:2026-10-12| 4人浏览过
原创

本文详解如何使用Python构建一个轻量级的爬虫代理池。通过抓取西祠胡同等免费代理网站,利用PyQuery解析数据并存入List,实现HTTP与HTTPS代理的分类管理。文章提供了代理有效性检测、随机调用及失效清理的核心代码逻辑,并探讨了基于分数的代理维护机制,帮助开发者应对403限制。

在进行网络数据爬取时,频繁遭遇403状态码是常见现象,这通常意味着目标网站对当前IP实施了访问频率限制。应对此类反爬机制的有效策略是使用代理IP,当主IP被封禁时,可切换至其他可用IP。大型机构通常采购稳定的付费代理服务,而个人开发者或资源有限的用户则多依赖网上提供的免费代理资源。

常见的做法是从互联网抓取一批免费代理IP,并将其持久化存储于Excel文件或数据库(如MySQL、Redis)中,通过定期维护确保代理的可用性。然而,这种方案存在环境依赖问题:若运行爬虫的机器未安装Excel或特定的数据库软件,代理池将无法正常运行。

鉴于作者此前从事Java开发,习惯将常用数据存入ArrayList以保证高效便捷,因此借鉴该经验,在Python中采用List列表来存储爬取的代理IP,构建一个内存中的代理池,并对其进行持续维护。

文中选取西祠胡同(xicidaili)和swei360等免费代理网站作为数据源,这些资源足以满足大多数常规爬虫需求。实现过程中需依赖requests和pyquery库,若未安装请自行补充。

首先介绍如何从西祠胡同网站抓取代理数据。需定义一个抓取方法,接收两个参数:目标URL和需要爬取的页数。具体实现代码如下:

def get_xicidaili_proxy(url,page):
  for i in range(1,page):
    headers = {
      "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36 SE 2.X MetaSr 1.0"}
    response = requests.get(url + str(i), headers=headers)

    html = response.text
    doc = pq(html)
    ip_list = doc('#ip_list')('tr:gt(0)').items()
    for item in ip_list:
      ip = item.find('td:nth-child(2)').text()
      port = item.find('td:nth-child(3)').text()
      http_type = item.find('td:nth-child(6)').text()
      proxy_ip = http_type + "://" + ip + ":" + port
      if http_type == 'HTTP':
        http_proxy_pool.append(proxy_ip)
      elif http_type == 'HTTPS':
        https_proxy_pool.append(proxy_ip)
      # print(proxy_ip)

代码中定义了http_proxy_pool和https_proxy_pool两个列表,分别用于存储HTTP和HTTPS类型的代理。利用PyQuery通过CSS选择器提取IP、端口及协议类型,并将其组合为“协议://IP:端口”格式的字符串,存入对应的代理列表中。

抓取swei360网站代理的原理与上述过程一致,此处不再赘述具体代码。

在使用代理前,必须验证其有效性。通过发送GET请求并检查返回状态码来判断:若返回200,则代理可用;其他状态码则视为不可用。相关验证代码如下:

def detect_proxy(test_url,http_type,proxy):
  headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36 SE 2.X MetaSr 1.0"}
  proxy={
    http_type : proxy
  }
  try:
    response = requests.get(test_url,proxies=proxy,headers=headers)
    if response.status_code in [200]:
      print('代理可用',proxy)
      return True
    else:
      print('代理不可用', proxy);
      delete_proxy(http_type,proxy)
      return False
  except(requests.exceptions.ProxyError,RequestException):
    print('代理不可用', proxy)
    delete_proxy(http_type, proxy)
    return False

定义detect_proxy方法用于检测代理状态,参数包括测试网址、代理类型(HTTP/HTTPS)及代理IP地址。若requests请求返回状态码200,则判定代理可用并返回True;否则返回False。若遇到requests异常或其他错误,同样视为不可用并返回False。对于检测为不可用的代理,需从代理池中移除。

从代理池获取代理时,采用随机抽取策略,以避免频繁使用同一IP导致被目标网站拒绝访问。具体实现代码如下:

def get_https_proxy():
  proxy_ip = random.choice(https_proxy_pool)
  return proxy_ip

def get_http_proxy():
  proxy_ip = random.choice(http_proxy_pool)
  return proxy_ip

为确保代理池的纯净度,一旦检测到代理不可用,应及时从http_proxy_pool或https_proxy_pool列表中将其删除。

至此,一个简单的爬虫代理池已搭建完成,核心流程总结如下:

  • 从免费代理网站抓取代理信息,并将其存储在List列表中。
  • 提供从代理池中随机获取代理的功能。鉴于HTTP和HTTPS网站对代理类型有特定要求,分别提供了获取HTTP和HTTPS类型代理的独立方法。
  • 提供检测代理有效性的方法,若代理可用返回True,不可用则返回False。
  • 提供删除失效代理的方法,以清理代理池。

当前实现的代理池较为简单,存在一个潜在缺陷:仅以状态码是否为200作为判断标准。若返回其他代码,可能由网络波动或测试网站不可访问引起,并不一定代表代理本身失效。更优的做法是为每个代理设置初始分值(如10分),检测不可用时扣分,分数归零时彻底移除;检测可用时重置为满分。

这种基于分数的机制为失效代理提供了“改过自新”的机会,避免了因单次网络波动而直接将其剔除的“一刀切”做法。

以上即为本文关于Python爬虫代理池搭建的全部内容,希望对读者有所帮助,欢迎支持本站。

相关标签:

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。