爬虫代理IP池项目,主要功能为定时采集网上发布的免费代理验证入库,定时验证入库的代理保证代理的可用性,提供API和CLI两种使用方式。同时你也可以扩展代理源以增加代理池IP的质量和数量。
****************************************************************
*** ______ ********************* ______ *********** _ ********
*** | ___ \_ ******************** | ___ \ ********* | | ********
*** | |_/ / \__ __ __ _ __ _ | |_/ /___ * ___ | | ********
*** | __/| _// _ \ \ \/ /| | | || __// _ \ / _ \ | | ********
*** | | | | | (_) | > < \ |_| || | | (_) | (_) || |___ ****
*** \_| |_| \___/ /_/\_\ \__ |\_| \___/ \___/ \_____/ ****
**** __ / / *****
************************* /___ / *******************************
************************* ********************************
****************************************************************
官网文档 | 链接
直接复制执行如下命令即可
sudo sed -e 's|^mirrorlist=|#mirrorlist=|g' \
-e 's|^#baseurl=http://mirror.centos.org|baseurl=https://mirrors.tuna.tsinghua.edu.cn|g' \
-i.bak \
/etc/yum.repos.d/CentOS-*.repo
更新软件包缓存
yum makecache
下载redis-5.0.5源码包
wget http://download.redis.io/releases/redis-5.0.5.tar.gz
解压
tar -xf redis-5.0.5.tar.gz
进入目标文件
cd redis-5.0.5
编译源码
make
复制环境到指定路径完成安装
cp -r redis-5.0.5 /usr/local/redis
配置redis可以后台启动:修改下方内容(你不加也可以)
vim /usr/local/redis/redis.conf
# 在配置文件中修改daemonize no 为yes
daemonize yes
# 完成配置修改
按esc,输入:wq
建立软连接
ln -s /usr/local/redis/src/redis-server /usr/bin/redis-server
ln -s /usr/local/redis/src/redis-cli /usr/bin/redis-cli
后台运行Redis
cd /usr/local/redis
redis-server ./redis.conf
客户端连接测试redis环境
redis-cli
测试Redis环境
127.0.0.1:6379> ping
PONG
退出redis环境
exit
更新系统
yum update
安装依赖包
yum install openssl-devel bzip2-devel expat-devel gdbm-devel readline- devel sqlite-devel gcc gcc-c++ openssl-devel libffi-devel python-devel mariadb-devel
安装开发工具包
yum -y groupinstall "Development tools"
安装wget
yum install wget
下载python安装包
wget https://www.python.org/ftp/python/3.6.8/Python-3.6.8.tar.xz
解压安装包
tar -xf Python-3.6.8.tar.xz
进入目标文件
cd Python-3.6.8
配置安装路径:/usr/local/python3
./configure --prefix=/usr/local/python3
编译并安装
make && make install
建立软连接:终端命令 python3,pip3
ln -s /usr/local/python3/bin/python3 /usr/bin/python3
ln -s /usr/local/python3/bin/pip3 /usr/bin/pip3
克隆远程仓库到proxy_pool目录下
git clone https://github.com/jhao104/proxy_pool.git ./proxy_pool
切换目录
cd proxy_pool/
安装依赖库
pip3 install -r requirements.txt
启动
python3 proxyPool.py schedule
由于我没有Redis没有设置密码,报错如下:
Traceback (most recent call last):
File "/app/db/redisClient.py", line 139, in test
self.getCount()
File "/app/db/redisClient.py", line 126, in getCount
...
2021-05-19 22:02:20,535 redisClient.py[line:144] ERROR redis connection error: Client sent AUTH, but no password is set
...
redis.exceptions.AuthenticationError: Client sent AUTH, but no password is set
2021-05-19 22:02:20,539 launcher.py[line:39] INFO exit!
给redis设置一个密码:
[root@oldboy proxy_pool]# redis-cli
127.0.0.1:6379> config set requirepass root
OK
所以修改配置文件
vim setting.py
修改配置DB_CONN
DB_CONN = 'redis://:root@127.0.0.1:6379/0'
再次运行项目并将进程运行丢到后台运行记录错误日志
[root@oldboy ~]# nohup python3 proxyPool.py schedule >> /var/log/proxy/proxy.log 2>&1 &
[1] 31859
查看代理池是否在运行
[root@oldboy ~]# ps -aux | grep 31859
root 4322 0.0 0.0 112808 972 pts/5 R+ 23:49 0:00 grep --color=auto 31859
然后再来验证redis中查询可用代理
[root@oldboy ~]# redis-cli
127.0.0.1:6379> keys *
(error) NOAUTH Authentication required.
127.0.0.1:6379> auth root
OK
127.0.0.1:6379> keys *
1) "use_proxy"
127.0.0.1:6379> HGETALL use_proxy #查询可用代理
1) "79.143.30.163:8080"
2) "{\"proxy\": \"79.143.30.163:8080\", \"fail_count\": 0, \"region\": \"\", \"type\": \"\", \"source\": \"\", \"check_count\": 1, \"last_status\": 1, \"last_time\": \"2021-05-19 23:45:00\"}"
....
70) "{\"proxy\": \"171.35.148.67:9999\", \"fail_count\": 0, \"region\": \"\", \"type\": \"\", \"source\": \"\", \"check_count\": 2, \"last_status\": 1, \"last_time\": \"2021-05-19 23:44:50\"}"
127.0.0.1:6379>
最后启动webApi服务
python3 proxyPool.py server
将webApi服务丢到台运行并记录日志
mkdir /var/log/proxyPool/
[root@oldboy proxy_pool]# nohup python3 proxyPool.py server >> /var/log/proxyPool/proxyPool.log 2>&1 &
[1] 24532
[root@oldboy ~]# ps -aux |grep 24532 # 查看运行状态
root 2142 0.0 0.0 112808 972 pts/5 R+ 00:08 0:00 grep --color=auto 24532
最后修改IP和端口在setting.py里面(不修改也可以)
vim setting.py
HOST = "0.0.0.0" # IP
PORT = 5000 # 监听端口
完成后按【ESC】-> 输入【 : 】-> 输入【wq】
在浏览器访问公网IP+端口即可,例如:http://127.0.0.1:5051/
安装docker
yum -y install docker
启动 docker 并设置开机启动
systemctl start docker
systemctl enable docker
拉取需要的镜像
docker pull redis
docker pull jhao104/proxy_pool
查看镜像
docker images
为了方便容器键进行通信,先为几个需要互相访问的容器单独创建一个网桥
docker network create -d bridge proxy_bridge
创建redis容器
docker run --name redis --network proxy_bridge -d redis
列出所有容器
docker ps
在运行的redis容器中执行命令
docker exec -it redis bash
进入redis容器
redis-cli --raw
测试redis环境
127.0.0.1:6379> ping
PONG
创建proxy pool的容器
docker run --name proxypool --network proxy_bridge -p 80:80 -d jhao104/proxy_pool:latest
查看日志:
docker logs proxypool
启动web服务后, 默认配置下会开启 http://127.0.0.1:5010 的api接口服务:
api | method | Description | arg |
---|---|---|---|
/ | GET | api介绍 | None |
/get | GET | 随机获取一个代理 | None |
/get_all | GET | 获取所有代理 | None |
/get_status | GET | 查看代理数量 | None |
/delete | GET | 删除代理 |
import requests
def get_proxy():
return requests.get("http://127.0.0.1:5010/get/").json()
def delete_proxy(proxy):
requests.get("http://127.0.0.1:5010/delete/?proxy={}".format(proxy))
# your spider code
def getHtml():
# ....
retry_count = 5
proxy = get_proxy().get("proxy")
while retry_count > 0:
try:
html = requests.get('http://www.example.com', proxies={"http": "http://{}".format(proxy)})
# 使用代理访问
return html
except Exception:
retry_count -= 1
# 删除代理池中代理
delete_proxy(proxy)
return None
项目默认包含几个免费的代理获取源,但是免费的毕竟质量有限,所以如果直接运行可能拿到的代理质量不理想。所以,提供了代理获取的扩展方法。
添加一个新的代理源方法如下:
1、首先在ProxyFetcher类中添加自定义的获取代理的静态方法, 该方法需要以生成器(yield)形式返回host:ip
格式的代理,例如:
class ProxyFetcher(object):
# ....
# 自定义代理源获取方法
@staticmethod
def freeProxyCustom1(): # 命名不和已有重复即可
# 通过某网站或者某接口或某数据库获取代理
# 假设你已经拿到了一个代理列表
proxies = ["x.x.x.x:3128", "x.x.x.x:80"]
for proxy in proxies:
yield proxy
# 确保每个proxy都是 host:ip正确的格式返回
2、添加好方法后,修改setting.py文件中的PROXY_FETCHER
项:
在PROXY_FETCHER
下添加自定义方法的名字:
PROXY_FETCHER = [
"freeProxy01",
"freeProxy02",
# ....
"freeProxyCustom1" # # 确保名字和你添加方法名字一致
]
schedule
进程会每隔一段时间抓取一次代理,下次抓取时会自动识别调用你定义的方法。