搭建代理池作用
平时我们爬取网站的时候,如果太频繁,容易导致IP被封。所以搭建代理池,每次随机获取可用的代理,伪装成其它IP去访问网站,能够有效防止爬虫被封禁,让爬虫脱离IP被封的苦海。
代理有很多免费的网站,但是不稳定。付费的代理池会相对稳定很多,具体看个人需求。
搭建代理池的准备工作
安装Redis数据库、此外Python要安装:aiohttp、requests 、redis-py 、pyquery、Flask。
这里介绍一下Redis数据库在代理池的作用:
这里我们使用 Redis 的有序集合,集合的每一个元素都是不重复的,对于代理池来说,集合的元 素就变成了一个个代理,也就是 IP 加端口的形式,如 60.207.237.111 :8888 ,这样的一个代理就是集合 的一个元素。 另外,有序集合的每一个元素都有一个分数字段,分数是可以重复的,可以是浮点数类 型,也可以是整数类型。 该集合会根据每一个元素的分数对集合进行排序,数值小的排在前面,数值 大的排在后面,这样就可以实现集合元素的排序了。 对于代理池来说,这个分数可以作为判断一个代理是否可用的标志, 100 为最高分,代表最可用, 0 为最低分,代表最不可用。 如果要获取可用代理,可以从代理池中随机获取分数最高的代理,注意 是随机,这样可以保证每个可用代理都会被调用到。
主要模块
存储、获取、检测、接口四个模块
存储:负责存储抓取下来的代理。 首先要保证代理不重复, 要标识代理的可用情况,还 要动态实时处理每个代理,所以一种比较高效和方便的存储方式就是使用 Redis 的 Sorted Set,即有序集合
获取:需要定时在各大代理网站抓取代理。 代理可以是免费公开代理也可以是付费代 理,代理的形式都是 IP 加端口,此模块尽量从不同来源获取,尽量抓取高匿代理,抓取成功 之后将可用代理保存到数据库中。
检测:需要定时检测数据库中的代理。 这里需要设置一个检测链接,最好是爬取哪个网 站就检测哪个网站,这样更加有针对性,如果要做一个通用型的代理,那可以设置百度等链 接来检测。 另外,我们需要标识每一个代理的状态,如设置分数标识, 100 分代表可用,分 数越少代表越不可用。 检测一次,如果代理可用,我们可以将分数标识立即设置为 100 满 分,也可以在原基础上加 l分;如果代理不可用,可以将分数标识减 l 分,当分数戚到一定阔 值后,代理就直接从数据库移除。 通过这样的标识分数,我们就可以辨别代理的可用情况, 选用的时候会更有针对性
接口:需要用 API 来提供对外服务的接口 。 其实我们可以直接连接数据库采取对应的数 据,但是这样就需要知道数据库的连接信息,并且要配置连接,而比较安全和方便的方式就 是提供一个 Web API 接口,我们通过访问接口即可拿到可用代理。 另外,由于可用代理可能 有多个,那么我们可以设置一个随机返回某个可用代理的接口,这样就能保证每个可用代理 都可以取到,实现负载均衡。
代码实现模块
写代码最忌讳的就是重复造成轮子(其实是懒),所以此刻就要奉上崔庆才大大的github代码了,本人亲测可用,但是有几个地方因为Redis库更新的问题,语法发生改变需要修改一下。
github地址:Python3WebSpider/ProxyPool
修改的地方都在bd.py这个文件里:
TEST_URL根据自己测试的网站替换就可以了。
目录
脚本点击run.py直接运行即可。
Redis数据库分数100即可用的
随机获取的链接:
selenium获取代理IP访问网站
从上面的代理池网站就可以随机获取可以用的IP,然后通过一下代码伪装成别的IP对抓取网站进行访问了
from selenium import webdriver import requests PROXY_POOL_URL = :5555/random response = requests.get(PROXY_POOL_URL) print(response.text) proxy = response.text #获取随机ip chrome_options = webdriver.ChromeOptions() chrome_options.add_argument(--proxy-server=http:// + proxy) #传入ip chrome_options.add_argument(headless)# 添加无头浏览 browser = webdriver.Chrome(options=chrome_options) url = browser.get(url)requests获取代理IP访问网站
import requests PROXY_POOL_URL = :5555/random response = requests.get(PROXY_POOL_URL) print(response.text) proxy = response.text #获取随机ip proxies = { http : http:// + proxy, https : https:// + proxy, } #传入ip res = requests.get(,proxies=proxies)