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 自动提交和抓取网页
Jul 13 Python
python采用requests库模拟登录和抓取数据的简单示例
Jul 05 Python
Python 序列的方法总结
Oct 18 Python
python获取代码运行时间的实例代码
Jun 11 Python
Django 中自定义 Admin 样式与功能的实现方法
Jul 04 Python
Python Django view 两种return的实现方式
Mar 16 Python
python 使用raw socket进行TCP SYN扫描实例
May 05 Python
Python使用Excel将数据写入多个sheet
May 16 Python
django有哪些好处和优点
Sep 01 Python
Python Merge函数原理及用法解析
Sep 16 Python
Kmeans均值聚类算法原理以及Python如何实现
Sep 26 Python
python 爬取免费简历模板网站的示例
Sep 27 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注入实例
2006/10/09 PHP
制作安全性高的PHP网站的几个实用要点
2014/12/30 PHP
php递归函数三种实现方法及如何实现数字累加
2015/08/07 PHP
学习php设计模式 php实现单例模式(singleton)
2015/12/07 PHP
php简单统计中文个数的方法
2016/09/30 PHP
php基于curl实现随机ip地址抓取内容的方法
2016/10/11 PHP
PHP+JQUERY操作JSON实例
2017/03/23 PHP
PHP number_format函数原理及实例解析
2020/07/14 PHP
jquery 多级下拉菜单核心代码
2010/05/21 Javascript
jQuery中:last-child选择器用法实例
2014/12/31 Javascript
nodejs实例解析(输出hello world)
2017/01/03 NodeJs
react-router实现跳转传值的方法示例
2017/05/27 Javascript
JavaScript循环_动力节点Java学院整理
2017/06/28 Javascript
浅谈redux, koa, express 中间件实现对比解析
2019/05/23 Javascript
详解Vue 项目中的几个实用组件(ts)
2019/10/29 Javascript
Vue+tracking.js 实现前端人脸检测功能
2020/04/16 Javascript
如何用JS模拟实现数组的map方法
2020/07/30 Javascript
微信小程序组件生命周期的踩坑记录
2021/03/03 Javascript
[02:39]DOTA2英雄基础教程 天怒法师
2013/11/29 DOTA
[34:10]Secret vs VG 2019国际邀请赛淘汰赛 败者组 BO3 第二场 8.24
2019/09/10 DOTA
[47:52]DOTA2-DPC中国联赛正赛 iG vs LBZS BO3 第二场 3月4日
2021/03/11 DOTA
python利用smtplib实现QQ邮箱发送邮件
2020/05/20 Python
Numpy中的mask的使用
2018/07/21 Python
Django model序列化为json的方法示例
2018/10/16 Python
Python对象转换为json的方法步骤
2019/04/25 Python
详解python websocket获取实时数据的几种常见链接方式
2019/07/01 Python
浅谈Keras中shuffle和validation_split的顺序
2020/06/19 Python
亚洲领先的旅游体验市场:Voyagin
2019/11/23 全球购物
某科技软件测试面试题
2013/05/19 面试题
机电一体化职业规划书
2014/01/07 职场文书
警示教育活动总结
2014/05/05 职场文书
报考公务员诚信承诺书
2014/08/29 职场文书
民间借贷借条范本
2015/05/25 职场文书
Python Matplotlib库实现画局部图
2021/11/17 Python
mongoDB数据库索引快速入门指南
2022/03/23 MongoDB
vue route新窗口跳转页面并且携带与接收参数
2022/04/10 Vue.js