为什么需要代理,这个就不需要再多做赘述了。现在在网上有许多的免费代理网站,但是用的时候就会发现,那些是真滴不好用,好用点的也都是需要收费的。所以为了省钱(土豪请自便),就需要做自己做一个动态的代理池,在网上不断的爬取有用的代理放入代理池中,定时的检测和更新,然后在使用的时候就直接在自己的代理池中调用就好了。现在在github上有许多的动态代理池的架构,这个是别人视频中提到的,肯定是一个很厉害的大神写的。当然也可能有其他更好用的,如果需要的话可以自己寻找。
这个架构主要是使用Redis和Flask来实现和维护的,源代码地址在:https://github.com/germey/proxypool。先分析一下整个代码的结构:整个代码大致分为两块,一个是运行实例,另外一个就是代理池的核心代码。下面有两个文件:run.py和setup.py,在终端执行python run.py就可以整个运行这个代码了,运行的时候请确保你的redis服务是开启的。
打开run文件,就能发现整个代码主要就是调用了schedule.py和api.py,api其实就是用flask写的一个接口,主要的代码其实是在调度器上的。而在schedule.py中的run方法上,其实是重新创建了两个进程:一个负责从网上获取代理,一个从数据库中读取代理并进行检测。
查看下获取和存储代理的方法即valid_proxy,在方法中声明了一个conn对象,ctrl+右键点击RedisClient,会进入到了db.py,这个是数据库的配置和方法,其中get方法中lrange和put方法中的rpush能够知道数据库的数据是从队列右侧放入从左侧提取的,这样就保证了数据的更新性,右侧的数据永远比左侧的要新。pop方法中使用了rpop,这个意思就是从右侧取出最新的代理,能保证代理的有效性。queue_len是队列的长度,flush是刷新整个队列。这个类(RedisClient)主要是提供了队列的相关api操作。声明的第二个对象是tester,这个主要是用于检测代理是否可用的。在class ValidityTester中最主要的方法就是test_single_proxy,它用了async,这个就是利用aiohttp这个库实现异步检测的一个方法(python3.5版本以后),每一个方法前面都需要使用async这个标识符。在测试前首先是组成真正的代理,在前面加上"http://",然后进行真正的测试方法就是:
其实就是获取test_api,这个api是一个全局的变量,在setting中,我们可以知道它其实就是百度。如果能正常访问的话,就存入到数据库,放入队列的右侧。在调度器的方法valid_proxy中将可用的代理存入到队列里,不可用的代理剔除。而且在方法中也有一个关于队列长度的判断,如果长度不够的话,就进入睡眠等待模式。这样就保证了代理的更新。
第二个进程就是检查代理池,在setting中也限定了代理池数量的大小:
就是代理池的数量界限,如果小于10的时候,就会获取代理,大于100的时候回停止获取。
在getter.py中是从网页获取代理的方法。定义了两个类,一个是元类:ProxyMetaclass,另一个是爬虫函数类: FreeProxyGetter,通过不同的爬虫方法获取不同网站的代理,然后返回一个生成器,就实现了不同网站的代理爬取。这个代码的可扩展性非常强,如果想要再添加不同网站的爬虫,只要重新定义一个以"crawl_"为开头的爬虫方法就行了。
这个架构的源代码地址是“https://github.com/germey/proxypool”,有需要的话可以自行下载。