运用squid轮询ip避免爬虫被封
阅读时长:3 min
爬虫使用过程中经常会遇到反爬限制的网站,爬的快一点就会被封IP网络上有很多免费代理随便扫描一批就可以使用.每增加一个代理IP爬取速度就会增加一倍,所以使用代理爬网站是最经济实用的。
首先是先安装squid.ubuntu系统直接使用下面的命令安装squid:
sudo apt-get install squid3
如果是centos系统就使用下面的命令安装:
yum -y install squid
windows下的安装自行百度。本人已成功安装并使用。
配置文件一般是在/etc/squid3/下的squid.conf文件,里边记录了待轮询的ip.ubuntu系统可以直接全部替换,centos对应修改就可以了.重启后就可以生效了.如果配置正确,ip可用,把代理ip换为squid的代理地址即可,如可以把浏览器的HTTP代理设置成127.0.0.1:6666或是服务器的IP.如果代理IP是免费采集的就需要写个脚本自动采集验证自动生成配置文件,然后重新载入配置文件或重启squid.
所以可以选择买少量的代理,再通过网上的开源框架采集一些免费的代理。网上已经有一些教程是基于IPpool的,本文用的是proxy_pool ,其使用方法可以参考github主页说明。
思路如下.
- 将获取到的代理服务器写入squid配置文件
- 解析网站提供的代理服务器,按照一定规则写入/etc/squid/squid.conf
- 重新配置squid
- 写入配置文件之后重新加载最新的文件,不会造成中断
- 自动更新,重复1-3
- 由于网站提供的代理存活时间有限,所以需要每隔一段时间重新获取一批新IP
使用方法
- 按Squid 搭建正向代理服务器、Squid 配置高匿代理介绍的方法搭建运行Squid高匿服务器
- 备份原始配置文件
cp /etc/squid.conf /etc/squid.conf.or
这里根据配置文件路径不同自行设置 - 在squid服务器上运行
python ippool.py
即如下python文件。代码是python3的,省心。
#!/usr/bin/env python
# coding: utf-8
from gevent import monkey
monkey.patch_all()
import os
import time
import logging
import requests
from gevent.pool import Pool
logger = logging.getLogger(__name__)
logger.setLevel(logging.INFO)
formatter = logging.Formatter(
'%(asctime)s - %(name)s - %(levelname)s: - %(message)s',
datefmt='%Y-%m-%d %H:%M:%S')
# 使用StreamHandler输出到屏幕
ch = logging.StreamHandler()
ch.setLevel(logging.INFO)
ch.setFormatter(formatter)
logger.addHandler(ch)
# Squid的配置文件语法
# 将请求转发到父代理
PEER_CONF = "cache_peer %s parent %s 0 no-query weighted-round-robin weight=1 connect-fail-limit=2 allow-miss max-conn=5\n"
# 可用代理
GOOD_PROXIES = []
pool = Pool(50)
def delete_proxy(proxy):
requests.get("http://127.0.0.1:5010/delete/?proxy={}".format(proxy))
def check_proxy(proxy):
#GOOD_PROXIES=[]
try:
html = requests.get('http://yingshi.51treenewbee.cn', proxies={"http": "http://{}".format(proxy)},timeout=10)
#assert proxy in html.content
logger.info('[GOOD] - {}'.format(proxy))
#GOOD_PROXIES.append(proxy)
return proxy
except Exception as e:
delete_proxy(proxy)
logger.error('[BAD] - {}, {}'.format(proxy, e))
return 'bad'
def update_conf(proxy1):
try:
with open('etc/squid.conf.or', 'r') as F:
squid_conf = F.readlines()
squid_conf.append('\n# Cache peer config\n')
for line in proxy1:
#采集代理ip端口分离
proxy=line.strip().split(':')
squid_conf.append(PEER_CONF % (proxy[0], proxy[1]))
with open('etc/squid.conf', 'w') as F:
F.writelines(squid_conf)
return True
logger.info('写入Squid配置文件成功')
except Exception as e:
logger.error(e)
return False
def get_proxy():
# 1. 获取代理IP资源
res = requests.get('http://127.0.0.1:5010/get_all').json()
try:
logger.info('get all proxies')
proxies = []
#检查良好的代理
Goodproxy=pool.map(check_proxy, res)
pool.join()
try:
while 'bad' in Goodproxy:
Goodproxy.remove('bad')
# 2. 写入Squid配置文件
except:
logger.info('检查到所有代理均可同,这是小概率事件,请检查配置')
update_conf(Goodproxy)
# 3. 重新加载配置文件
os.system('squid -k reconfigure -n Squid_Proxy')
logger.info('>>>> DONE! <<<<') except Exception as e: logger.error(e) def main(): timeRange=300 print('ip存入squid开始') start = time.time()-timeRange+2 while True: # 每30秒获取一批新IP if time.time() - start >= timeRange:
get_proxy()
start = time.time()
time.sleep(5)
if __name__ == '__main__':
main()