python单例模式获取IP代理的方法详解


Posted in Python onSeptember 13, 2018

引言

最近在学习python,先说一下我学Python得原因,一个是因为它足够好用,完成同样的功能,代码量会比其他语言少很多,有大量的丰富的库可以使用,基本上前期根本不需要自己造什么轮子。第二个是因为目前他很火,网上各种资料都比较丰富,且质量尚可。接下来不如正题

在学习Python爬虫的时候,经常会遇见所要爬取的网站采取了反爬取技术导致爬取失败。高强度、高效率地爬取网页信息常常会给网站服务器带来巨大压力,所以同一个IP反复爬取同一个网页,就很可能被封,这里讲述一个爬虫技巧,设置代理IP

为什么需要代理

提到python,虽然他能干的事情很多,但是我们首先想起的一般都是爬虫。爬虫的作用是通过抓取网页,分析并获得网页中的内容。像php这类语言也是可以用curl来达到爬虫的效果,不过论爬虫库的数量和易用性就没办法和python相比了。

对网络知识有了解的朋友应该知道,很多网站都有反爬虫的策略,或者是针对同一ip地址频繁请求会拒绝服务,我在刚开始写一些东西的时候就经常因为访问的频率太频繁而被禁。所以说仅用自己的ip地址进行爬取是有一定的局限性的。而代理就可以解决这个问题。

代理是什么

作为一个程序员我觉得有必要了解一些基本的网络知识,比如说网络代理。

我不想从哪里复制粘贴一段介绍过来,因为我觉得那样很low,我说说我理解的网络代理。

如果你不了解代理,你应该知道代购吧,比如你想买一个东西,却不想自己跑去买,可以找一个代理帮你去买。类似的,网络代理也是在你和目的网络之间的一个中转方。类似如下图

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, 如果使用2.7版本的代码需要微调

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 相关文章推荐
Python使用reportlab将目录下所有的文本文件打印成pdf的方法
May 20 Python
python制作小说爬虫实录
Aug 14 Python
python中类和实例如何绑定属性与方法示例详解
Aug 18 Python
10分钟教你用python动画演示深度优先算法搜寻逃出迷宫的路径
Aug 12 Python
python numpy存取文件的方式
Apr 01 Python
在Python中字符串、列表、元组、字典之间的相互转换
Nov 15 Python
python实现同一局域网下传输图片
Mar 20 Python
利用python生成照片墙的示例代码
Apr 09 Python
python怎么判断素数
Jul 01 Python
Python threading模块condition原理及运行流程详解
Oct 05 Python
python 获取谷歌浏览器保存的密码
Jan 06 Python
TensorFlow2.0使用keras训练模型的实现
Feb 20 Python
如何利用python制作时间戳转换工具详解
Sep 12 #Python
Python get获取页面cookie代码实例
Sep 12 #Python
python读取和保存图片5种方法对比
Sep 12 #Python
python3 拼接字符串的7种方法
Sep 12 #Python
python简单操作excle的方法
Sep 12 #Python
使用python实现快速搭建简易的FTP服务器
Sep 12 #Python
python ftp 按目录结构上传下载的实现代码
Sep 12 #Python
You might like
php性能优化分析工具XDebug 大型网站调试工具
2011/05/22 PHP
php封装的验证码工具类完整实例
2016/10/19 PHP
PHP Post获取不到非表单数据的问题解决办法
2018/02/27 PHP
PHP封装的验证码工具类定义与用法示例
2018/08/22 PHP
JavaScript实现把数字转换成中文
2015/06/29 Javascript
JavaScript Promise 用法
2016/06/14 Javascript
AngularJS 表达式详细讲解及实例代码
2016/07/26 Javascript
jsp 自动编译机制详细介绍
2016/12/01 Javascript
实现JavaScript高性能的数据存储
2016/12/11 Javascript
jQuery给表格添加分页效果
2017/03/02 Javascript
微信小程序 request接口的封装实例代码
2017/04/26 Javascript
JS 中document.write()的用法和清空的原因浅析
2017/12/04 Javascript
详解webpack require.ensure与require AMD的区别
2017/12/13 Javascript
微信小程序实现多个按钮的颜色状态转换
2019/02/15 Javascript
vue+elementUI实现表单和图片上传及验证功能示例
2019/05/14 Javascript
微信小程序自定义组件components(代码详解)
2019/10/21 Javascript
js实现飞机大战小游戏
2020/08/26 Javascript
vuex的使用和简易实现
2021/01/07 Vue.js
Vue常用API、高级API的相关总结
2021/02/02 Vue.js
[10:07]2014DOTA2国际邀请赛 实拍选手现场观战DK对阵Titan
2014/07/12 DOTA
python BeautifulSoup使用方法详解
2013/11/21 Python
python妹子图简单爬虫实例
2015/07/07 Python
Python利用operator模块实现对象的多级排序详解
2017/05/09 Python
python利用urllib和urllib2访问http的GET/POST详解
2017/09/27 Python
Python将string转换到float的实例方法
2019/07/29 Python
使用Python和OpenCV检测图像中的物体并将物体裁剪下来
2019/10/30 Python
python实现双色球随机选号
2020/01/01 Python
使用tensorboard可视化loss和acc的实例
2020/01/21 Python
python zip,lambda,map函数代码实例
2020/04/04 Python
Python用requests库爬取返回为空的解决办法
2021/02/21 Python
CSS中几个与换行有关的属性简明总结
2014/04/15 HTML / CSS
关于webview适配H5上传照片或者视频文件的方法
2020/11/04 HTML / CSS
人事聘任通知
2015/04/21 职场文书
jquery插件实现搜索历史
2021/04/24 jQuery
vue实现列表拖拽排序的示例代码
2022/04/08 Vue.js
TS 类型收窄教程示例详解
2022/09/23 Javascript