python单例模式获取IP代理的方法详解
引言
最近在学习python,先说一下我学Python得原因,一个是因为它足够好用,完成同样的功能,代码量会比其他语言少很多,有大量的丰富的库可以使用,基本上前期根本不需要自己造什么轮子。第二个是因为目前他很火,网上各种资料都比较丰富,且质量尚可。接下来不如正题
在学习Python爬虫的时候,经常会遇见所要爬取的网站采取了反爬取技术导致爬取失败。高强度、高效率地爬取网页信息常常会给网站服务器带来巨大压力,所以同一个IP反复爬取同一个网页,就很可能被封,这里讲述一个爬虫技巧,设置代理IP
为什么需要代理
提到python,虽然他能干的事情很多,但是我们首先想起的一般都是爬虫。爬虫的作用是通过抓取网页,分析并获得网页中的内容。像php这类语言也是可以用curl来达到爬虫的效果,不过论爬虫库的数量和易用性就没办法和python相比了。
对网络知识有了解的朋友应该知道,很多网站都有反爬虫的策略,或者是针对同一ip地址频繁请求会拒绝服务,我在刚开始写一些东西的时候就经常因为访问的频率太频繁而被禁。所以说仅用自己的ip地址进行爬取是有一定的局限性的。而代理就可以解决这个问题。
代理是什么
作为一个程序员我觉得有必要了解一些基本的网络知识,比如说网络代理。
我不想从哪里复制粘贴一段介绍过来,因为我觉得那样很low,我说说我理解的网络代理。
如果你不了解代理,你应该知道代购吧,比如你想买一个东西,却不想自己跑去买,可以找一个代理帮你去买。类似的,网络代理也是在你和目的网络之间的一个中转方。类似如下图
Alice->agency(代理):IwanttogetsthfromBob
agency(代理)->Bob:givemesth
NoterightofBob:Bobthinks
Bob-->agency(代理):thereissth!
agency(代理)-->Alice:bobgiveyousth
这里有一个问题是,普通代理是比较好检测出来的,有些网站不允许使用代理访问。这时候可以使用高匿代理可以解决这个问题。关于代理不多说了,有兴趣的可以自己去了解。
从哪里获取代理
这问题就简单了,直接百度搜索网络代理可以搜索到很多免费的,免费的一般不太稳定,应付日常需求应该没问题。如果需要稳定代理还是老老实实的花钱买付费的好一些,不要因小失大。
比如网上就经常推荐的代理
西祠代理: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-*- ''' Createdon2018-04-27 @author:Vinter_he ''' user_agents=[ 'Mozilla/5.0(Windows;U;WindowsNT5.1;it;rv:1.8.1.11)Gecko/20071127Firefox/2.0.0.11', 'Opera/9.25(WindowsNT5.1;U;en)', 'Mozilla/4.0(compatible;MSIE6.0;WindowsNT5.1;SV1;.NETCLR1.1.4322;.NETCLR2.0.50727)', 'Mozilla/5.0(compatible;Konqueror/3.5;Linux)KHTML/3.5.5(likeGecko)(Kubuntu)', 'Mozilla/5.0(X11;U;Linuxi686;en-US;rv:1.8.0.12)Gecko/20070731Ubuntu/dapper-securityFirefox/1.5.0.12', 'Lynx/2.8.5rel.1libwww-FM/2.14SSL-MM/1.4.1GNUTLS/1.2.9' "Mozilla/5.0(WindowsNT6.1;WOW64)AppleWebKit/537.1(KHTML,likeGecko)Chrome/22.0.1207.1Safari/537.1", "Mozilla/5.0(X11;CrOSi6862268.111.0)AppleWebKit/536.11(KHTML,likeGecko)Chrome/20.0.1132.57Safari/536.11", "Mozilla/5.0(WindowsNT6.1;WOW64)AppleWebKit/536.6(KHTML,likeGecko)Chrome/20.0.1092.0Safari/536.6", "Mozilla/5.0(WindowsNT6.2)AppleWebKit/536.6(KHTML,likeGecko)Chrome/20.0.1090.0Safari/536.6", "Mozilla/5.0(WindowsNT6.2;WOW64)AppleWebKit/537.1(KHTML,likeGecko)Chrome/19.77.34.5Safari/537.1", "Mozilla/5.0(X11;Linuxx86_64)AppleWebKit/536.5(KHTML,likeGecko)Chrome/19.0.1084.9Safari/536.5", "Mozilla/5.0(WindowsNT6.0)AppleWebKit/536.5(KHTML,likeGecko)Chrome/19.0.1084.36Safari/536.5", "Mozilla/5.0(WindowsNT6.1;WOW64)AppleWebKit/536.3(KHTML,likeGecko)Chrome/19.0.1063.0Safari/536.3", "Mozilla/5.0(WindowsNT5.1)AppleWebKit/536.3(KHTML,likeGecko)Chrome/19.0.1063.0Safari/536.3", "Mozilla/5.0(Macintosh;IntelMacOSX10_8_0)AppleWebKit/536.3(KHTML,likeGecko)Chrome/19.0.1063.0Safari/536.3", "Mozilla/5.0(WindowsNT6.2)AppleWebKit/536.3(KHTML,likeGecko)Chrome/19.0.1062.0Safari/536.3", "Mozilla/5.0(WindowsNT6.1;WOW64)AppleWebKit/536.3(KHTML,likeGecko)Chrome/19.0.1062.0Safari/536.3", "Mozilla/5.0(WindowsNT6.2)AppleWebKit/536.3(KHTML,likeGecko)Chrome/19.0.1061.1Safari/536.3", "Mozilla/5.0(WindowsNT6.1;WOW64)AppleWebKit/536.3(KHTML,likeGecko)Chrome/19.0.1061.1Safari/536.3", "Mozilla/5.0(WindowsNT6.1)AppleWebKit/536.3(KHTML,likeGecko)Chrome/19.0.1061.1Safari/536.3", "Mozilla/5.0(WindowsNT6.2)AppleWebKit/536.3(KHTML,likeGecko)Chrome/19.0.1061.0Safari/536.3", "Mozilla/5.0(X11;Linuxx86_64)AppleWebKit/535.24(KHTML,likeGecko)Chrome/19.0.1055.1Safari/535.24", "Mozilla/5.0(WindowsNT6.2;WOW64)AppleWebKit/535.24(KHTML,likeGecko)Chrome/19.0.1055.1Safari/535.24" ] 获取代理代码 #!/usr/bin/python #-*-coding:utf-8-*- '''
获取快代理ip获取到的为https://...格式
''' fromlxmlimportetree importsys,user_agents,random,requests,time classgeKuaidailiIp: __instance=None #使用单例模式 def__new__(cls): ifcls.__instance==None: cls.__instance=object.__new__(cls) cls.init(cls) returncls.__instance definit(self): print('初始化') self.proxieList=[] self.lastTime=time.time()-3601 self.agencyUrl='https://www.kuaidaili.com/free/' self.userAgents=user_agents.user_agents #获取user-agent defgetUserAgent(self): userAgent=random.choice(self.userAgents) return{ 'User-Agent':userAgent } defgetHtml(self,url): response=requests.get(url=url,headers=self.getUserAgent(),timeout=10).text #sys.exit() html=etree.HTML(response) returnhtml #取一页的分析代理ip defparseHtmlToGetIpList(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="类型"]') returntype,ip,port #取五页数据并进行拼接成一个list defgetProxies(self): #1小时获取一次代理否则会被禁 iftime.time()-self.lastTime>60*60: self.proxieList=[] self.lastTime=time.time() #只取前五页,因为后面的失效的会比较多,看自己需要 foriinrange(5): url=self.agencyUrl+'inha/'+str(i+1)+"/" type,ip,port=self.parseHtmlToGetIpList(url) count=len(port) foriinrange(count): self.proxieList.append(type[i].text+"://"+ip[i].text+":"+port[i].text) time.sleep(1) print('获取代理') returnself.proxieList defgetRandomAgencyIp(self): self.getProxies() ip=random.choice(self.proxieList) returnip #初始化代理用来进行测试用 #agency=geKuaidailiIp() #whileTrue: # #print(agency.getRandomAgencyIp()) #time.sleep(random.randint(4,10))
为什么使用单例模式
如果你可以保证自己只创建一个代理对象的话,其实并不是必须使用单例模式。因为很多朋友可能会把创建对象的代码写在循环中,导致频繁的获取代理而导致自己的ip被代理方禁了。单例模式保证在一次执行脚本过程中只有一个对象。如果对象已经创建,则直接返回已经创建的对象,从而控制不会频繁的访问快代理的页面。代码中是一小时一次。
题外话
其实早在七八年前上学期间我就接触过python,那时候python没有现在那么火,我还是在查怎么成为一名黑客的时候查到的这是一个必修课。然而当时还是比较贪玩的,学习资料也很匮乏。所以不就久放弃了。现在在人工智能和大数据的带动下,前几天看统计,python已经成了排名第一的脚本语言(php是世界上最好的语言,哥哥们别喷我),所以我几个月前开始每天抽一点业余时间学习python。幸运的是我有三门语言基础,学习起来还算比较轻松。如果你也是一名程序员,并且有精力也希望你能在业余时间做点什么学点什么来提高自己,与大家共勉。
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对毛票票的支持。