Python实现单例模式获取高匿IP代理的完整指南

周叙
周叙
发布时间:2026-10-13 | 8人浏览过
原创

本文详解如何在Python爬虫中利用单例模式高效获取高匿IP代理。针对网站反爬机制,通过复用代理对象避免频繁请求被封禁,结合User-Agent随机切换提升成功率。文章提供基于快代理的完整代码实现,涵盖Python 3.6环境下的代理获取、解析及单例类设计,助开发者稳定运行爬虫任务。

引言

近期我开始深入研习Python,主要基于两点考量:首先,Python具备极高的开发效率,在实现相同功能时,其代码量显著少于其他编程语言,且拥有庞大而丰富的第三方库支持,使得在开发初期几乎无需重复造轮子。其次,Python当前热度极高,网络上的学习资料不仅数量丰富,且整体质量较为可靠。接下来,我们将进入正题。

在进行Python网络爬虫开发时,常会遇到目标网站部署了反爬取技术,导致抓取任务失败。由于高强度、高效率地爬取网页信息会给服务器带来巨大压力,若同一IP地址反复请求同一网页,极易触发封禁机制。为此,本文将介绍一种关键的爬虫技巧:配置代理IP以规避风险。

为什么需要代理

提及Python,尽管其应用领域广泛,但大众首先联想到的往往是网络爬虫。爬虫的核心功能在于抓取网页并解析其中的内容。虽然PHP等语言也能通过curl库实现类似爬虫效果,但在爬虫库的丰富程度和易用性方面,Python具有明显优势。

具备一定网络知识基础的开发者应当知晓,许多网站设有反爬虫策略,特别是针对同一IP地址频繁请求的情况会拒绝服务。我在初期编写爬虫程序时,常因访问频率过高而被禁止访问。因此,仅依赖单一IP地址进行爬取存在明显的局限性,而引入代理机制则能有效解决这一问题。

代理是什么

作为开发人员,了解基础的网络知识至关重要,其中网络代理是核心概念之一。

我不打算直接复制粘贴一段枯燥的定义,因为那样显得缺乏诚意。这里分享我对网络代理的个人理解。

若你对代理概念陌生,不妨参考现实生活中的“代购”模式。例如,你想购买某件商品却不愿亲自前往,可以委托代理人代为购买。同理,网络代理充当了你与目标服务器之间的中转角色,其工作原理可参考下图示意。

Alice->agency(代理): I want to get sth from Bob agency(代理)->Bob: give me sth Note right of Bob: Bob thinks Bob-->agency(代理): there is sth! agency(代理)-->Alice: bob give you sth

需要注意的是,普通代理容易被检测出来,部分网站会禁止通过代理访问。此时,使用高匿代理可有效解决此问题。关于代理类型的更多细节,有兴趣的读者可自行深入研究。

从哪里获取代理

获取代理的途径相对简单,通过搜索引擎搜索“网络代理”即可找到大量免费资源。然而,免费代理通常稳定性较差,仅能满足日常基础需求。若追求高稳定性,建议购买付费代理服务,切勿因小失大。

例如,网络上常推荐的代理服务商包括:

西祠代理:http://www.xicidaili.com/nn/

本文示例采用快代理:https://www.kuaidaili.com/

起初我也使用了西祠代理,但因频繁访问导致账号被禁用,数日后才解封。在此期间,我切换至快代理,并重写了规则,设定每小时获取一次代理列表。

代码

本文示例基于Python 3.6.5版本编写。若使用Python 2.7版本,代码需进行相应微调。

User-Agent

User-Agent用于模拟不同的浏览器环境,直接复用即可。我的实现文件名为user_agents.py。

#!/usr/bin/python
# -*- coding:utf-8 -*-
'''
Created on 2018-04-27

@author: Vinter_he
'''

user_agents = [
 'Mozilla/5.0 (Windows; U; Windows NT 5.1; it; rv:1.8.1.11) Gecko/20071127 Firefox/2.0.0.11',
 'Opera/9.25 (Windows NT 5.1; U; en)',
 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)',
 'Mozilla/5.0 (compatible; Konqueror/3.5; Linux) KHTML/3.5.5 (like Gecko) (Kubuntu)',
 'Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.0.12) Gecko/20070731 Ubuntu/dapper-security Firefox/1.5.0.12',
 'Lynx/2.8.5rel.1 libwww-FM/2.14 SSL-MM/1.4.1 GNUTLS/1.2.9'
 
 "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/22.0.1207.1 Safari/537.1",
 "Mozilla/5.0 (X11; CrOS i686 2268.111.0) AppleWebKit/536.11 (KHTML, like Gecko) Chrome/20.0.1132.57 Safari/536.11",
 "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.6 (KHTML, like Gecko) Chrome/20.0.1092.0 Safari/536.6",
 "Mozilla/5.0 (Windows NT 6.2) AppleWebKit/536.6 (KHTML, like Gecko) Chrome/20.0.1090.0 Safari/536.6",
 "Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/19.77.34.5 Safari/537.1",
 "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/536.5 (KHTML, like Gecko) Chrome/19.0.1084.9 Safari/536.5",
 "Mozilla/5.0 (Windows NT 6.0) AppleWebKit/536.5 (KHTML, like Gecko) Chrome/19.0.1084.36 Safari/536.5",
 "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1063.0 Safari/536.3",
 "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1063.0 Safari/536.3",
 "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_0) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1063.0 Safari/536.3",
 "Mozilla/5.0 (Windows NT 6.2) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1062.0 Safari/536.3",
 "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1062.0 Safari/536.3",
 "Mozilla/5.0 (Windows NT 6.2) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1061.1 Safari/536.3",
 "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1061.1 Safari/536.3",
 "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1061.1 Safari/536.3",
 "Mozilla/5.0 (Windows NT 6.2) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1061.0 Safari/536.3",
 "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/535.24 (KHTML, like Gecko) Chrome/19.0.1055.1 Safari/535.24",
 "Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/535.24 (KHTML, like Gecko) Chrome/19.0.1055.1 Safari/535.24"
]
获取代理代码
#!/usr/bin/python
# -*- coding:utf-8 -*-
'''

获取快代理IP,返回格式为https://...。

'''
from lxml import etree
import sys ,user_agents ,random ,requests ,time

class geKuaidailiIp:
 __instance = None
 #使用单例模式
 def __new__(cls):
  if cls.__instance == None:
   cls.__instance = object.__new__(cls)
   cls.init(cls)
  return cls.__instance

 def init(self):
  print('初始化')
  self.proxieList = []
  self.lastTime = time.time() - 3601
  self.agencyUrl = 'https://www.kuaidaili.com/free/'
  self.userAgents = user_agents.user_agents
 # 获取user-agent
 def getUserAgent(self):
  userAgent = random.choice(self.userAgents)
  return {
   'User-Agent': userAgent
  }

 def getHtml(self,url):
  response = requests.get(url = url ,headers = self.getUserAgent(),timeout = 10).text
  # sys.exit()
  html = etree.HTML(response)
  return html
 #取一页的分析代理ip
 def parseHtmlToGetIpList(self,url):

  #获取代理ip地址 只取前五页
  html = self.getHtml(url)
  ip = html.xpath('//tr/td[@data-title = "IP"]')
  port = html.xpath('//tr/td[@data-title = "PORT"]')
  type = html.xpath('//tr/td[@data-title = "类型"]')
  return type, ip, port
 # 取五页数据并进行拼接成一个list
 def getProxies(self):
  # 1小时获取一次代理 否则会被禁
  if time.time() - self.lastTime > 60*60:
   self.proxieList =[]
   self.lastTime = time.time()
   #只取前五页,因为后面的失效的会比较多,看自己需要
   for i in range(5):
    url = self.agencyUrl+'inha/'+str(i+1)+"/"
    type,ip,port = self.parseHtmlToGetIpList(url)
    count = len(port)
    for i in range(count):
     self.proxieList.append(type[i].text+"://"+ip[i].text+":"+port[i].text)
    time.sleep(1)
   print('获取代理')
  return self.proxieList

 def getRandomAgencyIp(self):
  self.getProxies()
  ip = random.choice(self.proxieList)
  return ip


#初始化代理 用来进行测试用
# agency = geKuaidailiIp()
# while True:
#
#  print(agency.getRandomAgencyIp())
#  time.sleep(random.randint(4,10))

为什么使用单例模式

若能确保仅创建一个代理对象,则并非必须使用单例模式。然而,许多开发者将创建对象的代码置于循环中,导致频繁获取新代理,进而可能因请求过快被代理服务商封禁IP。单例模式保证在脚本执行期间仅存在一个代理对象实例。若对象已创建,则直接返回该实例,从而控制对快代理页面的访问频率。在代码设计中,我设定为每小时获取一次新代理。

题外话

事实上,早在七八年前求学期间,我便接触过Python。彼时Python尚未如今日般火爆,我是在查询如何成为黑客的过程中发现这是必修课之一。然而当时较为贪玩,且学习资料匮乏,因此不久后便放弃了学习。如今,在人工智能和大数据浪潮的推动下,据近期统计,Python已成为排名第一的脚本语言(注:PHP常被戏称为“世界上最好的语言”,请各位同行勿喷)。因此,我在几个月前开始每天利用业余时间学习Python。幸运的是,由于我已有三门编程语言的基础,学习过程相对轻松。如果你也是程序员,并有余力希望利用业余时间学习新技能以提升自我,愿与诸君共勉。

总结

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对本站的支持。

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表