声明:此篇文章主要是观看静觅教学视频后作的笔记,原教程地址https://cuiqingcai.com/python
普通代理git
由于以前都是学习测试,不须要对网站频繁的搜索爬取,因此代理使用彷佛关系不大,不过为了防止IP被封,也是一个很重要的知识点。以前使用代理也都是查找一些代理网站,手动将IP设置添加到proxies参数中,比较麻烦,并且代理IP也有可能出现没法正常访问的状况github
import requests proxies = { "http": "http://127.0.0.1:9743", "https": "https://127.0.0.1:9743", } response = requests.get("https://www.taobao.com", proxies=proxies)
维护代理池web
1.为何要用代理池许多网站有专门的反爬虫措施,可能遇到封IP等问题
①互联网上公开了大量免费代理,利用好资源
②经过定时的检测维护一样能够获得多个可用代理redis
2.代理池的要求
①多站抓取,异步检测
②定时筛选,持续更新
③提供接口,易于提取数据库
3.代理池的架构
服务器
4.代理池的获取途径
如今,新增一个解决思路,那就是经过Flask+Redis维护代理池。免费代理的质量可能不是太好,可能一个代理无数我的在用也说不定,主要实现就是从免费代理网站大量抓取这些免费代理,而后筛选出其中可用的代理存储起来供咱们使用,不可用的进行剔除,以西刺免费代理IP为例 架构
能够看到网页里提供了一些免费代理列表,包括服务器地址、端口、代理种类、地区、更新时间等等信息。当前咱们须要的就是代理服务器和端口信息,将其爬取下来便可app
5.维护代理
代理被爬取下来以后,就要解决代理的保存问题。首先咱们须要确保的目标是能够边取边存,另外还须要定时检查队列中不可用的代理将其剔除,因此须要易于存取。
另外怎样区分哪些是最新的可用的,哪些是旧的,若是用修改时间来标注是能够的,不过更简单的方法就是维护一个队列,只从一端存入,例如右端,这样就能确保最新的代理在队列右端,而在左端则是存入时间较长的代理,若是要取一个可用代理,从队列右端取一个就行了。那么对于队列的左端,不能让它一直老化下去,还须要作的操做就是定时从队列左端取出代理,而后进行检测,若是可用,从新将其加入右端
经过以上操做,就保证了代理一直是最新可用的。因此目前来看,既能高效处理,又能够作到队列动态维护,合适的方法就是利用Redis数据库的队列。能够定义一个类来维护一个Redis队列,好比get方法是批量从左端取出代理,put方法是从右端放入可用代理,pop方法是从右端取出最新可用代理异步
import redis from proxypool.error import PoolEmptyError from proxypool.setting import HOST, PORT class RedisClient(object): def __init__(self, host=HOST, port=PORT): self._db = redis.Redis(host, port) def get(self, count=1): proxies = self._db.lrange("proxies", 0, count - 1) self._db.ltrim("proxies", count, -1) return proxies def put(self, proxy): self._db.rpush("proxies", proxy) def pop(self): try: return self._db.rpop("proxies").decode('utf-8') except: raise PoolEmptyError
6.检测代理
可使用这个代理来请求某个站点,好比百度,若是得到正常的返回结果,那证实代理可用,不然代理不可用
import requests conn = RedisClient() proxies = {'http': proxy} r = requests.get('https://www.baidu.com', proxies=proxies) if r.status_code == 200: conn.put(proxy)
7.获取可用代理
经过redis-desktop能够看到一个proxies的键,其内容就是一些可用的IP代理,也就是所维护的代理池
维护了一个代理池,那么这个代理池须要是能够公用的。好比如今有多个爬虫项目都须要用到代理,而代理池的维护做为另外的一个项目,他们之间若是要创建链接,最恰当的方式就是接口。因此能够利用Web服务器来实现一个接口,其余的项目经过请求这个接口获得内容获取到一个可用代理,这样保证了代理池的通用性。因此要实现这个还须要一个Web服务器,例如Flask,Tornado等等。例如使用Flask,定义一个路由,而后调用RedisClient的pop方法,返回结果便可
@app.route('/') def get_proxy(): conn = RedisClient() return conn.pop()
这样一来,整个程序运行起来后,请求网页就能够看到一个可用代理了
8.使用代理
使用代理时只须要请求这个站点,就能够拿到可以使用的代理了。
def get_proxy(): r = requests.get('http://127.0.0.1:5000') return r.text def crawl(url, proxy): proxies = {'http': get_proxy()} r = requests.get(url, proxies=proxies) # do something
能够定义一个简单的方法,返回网页内容即代理,而后在爬取方法里设置代理使用便可
10.代理池功能测试
在了解了前面内容以后,现学现用,立刻用代理池测试访问了个人站点
11.代理池完整源码
我是从崔家华老师的github上下载下来的,源码可参考:https://github.com/Germey/ProxyPool
下载后发现源码不能正常安装,发现是在setup.py文件中有个参数配置错误
# 将 packages=[ 'proxy-pool' ], # 改成 packages=[ 'proxypool' ],
修改后的项目地址:https://github.com/XiaoFei-97/ProxyPool
原文出处:https://www.jzfblog.com/detail/68,文章的更新编辑以此连接为准。欢迎关注源站文章!