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创建只读属性对象的方法(ReadOnlyObject)
Feb 10 Python
Python中optionParser模块的使用方法实例教程
Aug 29 Python
python基于phantomjs实现导入图片
May 13 Python
python不换行之end=与逗号的意思及用途
Nov 21 Python
利用numpy和pandas处理csv文件中的时间方法
Apr 19 Python
使用django-guardian实现django-admin的行级权限控制的方法
Oct 30 Python
对pandas数据判断是否为NaN值的方法详解
Nov 06 Python
python面向对象 反射原理解析
Aug 12 Python
django之自定义软删除Model的方法
Aug 14 Python
Python 读取 YUV(NV12) 视频文件实例
Dec 09 Python
python解析多层json操作示例
Dec 30 Python
python wav模块获取采样率 采样点声道量化位数(实例代码)
Jan 22 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
一键删除顽固的空文件夹 软件下载
2007/01/26 PHP
php中支持多种编码的中文字符串截取函数!
2007/03/20 PHP
pdo中使用参数化查询sql
2011/08/11 PHP
php更新修改excel中的内容实例代码
2014/02/26 PHP
PHP的Yii框架中View视图的使用进阶
2016/03/29 PHP
PHP排序算法之堆排序(Heap Sort)实例详解
2018/04/21 PHP
PHP合并两个或多个数组的方法
2019/01/20 PHP
jQuery 性能优化指南 (1)
2009/05/21 Javascript
jquery 双色表格实现代码
2009/12/08 Javascript
javascript数组操作(创建、元素删除、数组的拷贝)
2014/04/07 Javascript
Jquery幻灯片特效代码分享--鼠标点击按钮时切换(1)
2015/08/15 Javascript
jQuery解析json数据实例分析
2015/11/24 Javascript
Nodejs中session的简单使用及通过session实现身份验证的方法
2016/02/04 NodeJs
js中常用的Tab切换效果(推荐)
2016/08/30 Javascript
JS实现按钮控制计时开始和停止功能
2017/07/27 Javascript
vue组件 $children,$refs,$parent的使用详解
2017/07/31 Javascript
为jquery的ajax请求添加超时timeout时间的操作方法
2018/09/04 jQuery
浅谈vue项目,访问路径#号的问题
2020/08/14 Javascript
Python实现的石头剪子布代码分享
2014/08/22 Python
在Python下使用Txt2Html实现网页过滤代理的教程
2015/04/11 Python
将Django框架和遗留的Web应用集成的方法
2015/07/24 Python
Python wxPython库消息对话框MessageDialog用法示例
2018/09/03 Python
Django 开发环境与生产环境的区分详解
2019/07/26 Python
基于python traceback实现异常的获取与处理
2019/12/13 Python
pymysql模块的操作实例
2019/12/17 Python
pandas分批读取大数据集教程
2020/06/06 Python
Django封装交互接口代码
2020/07/12 Python
Sunglasses Shop瑞典:欧洲领先的太阳镜网上商店
2018/04/22 全球购物
英国领先的独立时装店:Van Mildert
2019/10/28 全球购物
JENNIFER BEHR官网:各种耳环和发饰
2020/06/07 全球购物
党支部承诺书范文
2014/03/28 职场文书
大学班级学风建设方案
2014/05/01 职场文书
毕业生银行实习自我鉴定
2014/10/14 职场文书
小学2016年第十八届推普周活动总结
2016/04/05 职场文书
Python socket如何解析HTTP请求内容
2022/02/12 Python
从零开始在Centos7上部署SpringBoot项目
2022/04/07 Servers