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进行数据科学工作的简单入门教程
Apr 01 Python
Python编程中time模块的一些关键用法解析
Jan 19 Python
python机器学习之神经网络(一)
Dec 20 Python
python实现冒泡排序算法的两种方法
Mar 10 Python
人脸识别经典算法一 特征脸方法(Eigenface)
Mar 13 Python
Python cookbook(数据结构与算法)同时对数据做转换和换算处理操作示例
Mar 23 Python
python 日期操作类代码
May 05 Python
如何实现删除numpy.array中的行或列
May 08 Python
Python Subprocess模块原理及实例
Aug 26 Python
Django 创建后台,配置sqlite3教程
Nov 18 Python
Python3并发写文件与Python对比
Nov 20 Python
python上selenium的弹框操作实现
Jul 13 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多线程批量采集下载美女图片的实现代码(续)
2013/06/03 PHP
PHP中替换键名的简易方法示例详解
2014/01/07 PHP
MAC下通过改apache配置文件切换php多版本的方法
2017/04/26 PHP
php在windows环境下获得cpu内存实时使用率(推荐)
2018/02/08 PHP
juqery 学习之三 选择器 层级 基本
2010/11/25 Javascript
js 实现日期灵活格式化的小例子
2013/07/14 Javascript
2014年50个程序员最适用的免费JQuery插件
2014/12/15 Javascript
关于JS中prototype的理解
2015/09/07 Javascript
JavaScript人脸识别技术及脸部识别JavaScript类库Tracking.js
2015/09/14 Javascript
前端js文件合并的三种方式推荐
2016/05/19 Javascript
浅谈js多维数组和hash数组定义和使用
2016/07/27 Javascript
AngularJS实现标签页的两种方式
2016/09/05 Javascript
如何重置vue打印变量的显示方式
2017/12/06 Javascript
优雅的在React项目中使用Redux的方法
2018/11/10 Javascript
Auto.JS实现抖音刷宝等刷视频app,自动点赞,自动滑屏,自动切换视频功能
2020/05/08 Javascript
[59:15]完美世界DOTA2联赛PWL S2 LBZS vs FTD.C 第一场 11.20
2020/11/20 DOTA
Pyramid Mako模板引入helper对象的步骤方法
2013/11/27 Python
使用Django Form解决表单数据无法动态刷新的两种方法
2017/07/14 Python
Python字符串格式化输出代码实例
2019/11/22 Python
Python线程条件变量Condition原理解析
2020/01/20 Python
浅谈Python中range与Numpy中arange的比较
2020/03/11 Python
Flask缓存静态文件的具体方法
2020/08/02 Python
全球虚拟主机商:HostGator
2017/02/06 全球购物
毕业生在校学习的自我评价分享
2013/10/08 职场文书
董事长秘书岗位职责
2013/11/29 职场文书
病媒生物防治方案
2014/05/13 职场文书
信息管理专业自荐书
2014/06/05 职场文书
云南省召开党的群众路线教育实践活动总结会议新闻稿
2014/10/21 职场文书
仓库保管员岗位职责
2015/02/09 职场文书
结婚通知短信怎么写
2015/04/17 职场文书
2015年酒店前台工作总结
2015/04/20 职场文书
论文致谢词范文
2015/05/14 职场文书
学校证明范文
2015/06/24 职场文书
2016婚礼主持词开场白
2015/11/24 职场文书
解决spring.thymeleaf.cache=false不起作用的问题
2022/06/10 Java/Android
关于mysql中string和number的转换问题
2022/06/14 MySQL