tags:python python 单例模式 python 获取 ip 代理
引言: 最近在学习 python, 先说一下我学 Python 得原因, 一个是因为它足够好用, 完成同样的功能, 代码量会比其他语言少很多, 有大量的丰富的库可以使用, 基本上前期根本不需要自己造什么轮子. 第二个是因为目前他很火, 网上各种资料都比较丰富, 且质量尚可. 接下来不如正题
为什么需要代理
提到 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. 幸运的是我有三门语言基础, 学习起来还算比较轻松. 如果你也是一名程序员, 并且有精力也希望你能在业余时间做点什么学点什么来提高自己, 与大家共勉.
来源: https://www.cnblogs.com/vinter/p/8962698.html