这是第一次亲手尝试写代理池,之前在网站找了很多教程都没有看懂,于是按照自己的思路写一个简易版,目前这个是雏形,后面要加进多线程来检验IP以及通过更多的代理网站来爬取有效IP,该脚本主要思路是启动程序时,会自动测试数据库里面的ip,如果有效ip少于一定数目,会进行重新爬取有效ip,然后入库,如果数量足够,则不进行爬取
这次用到的代理网站是http://www.xicidaili.com/nn/
这是封装的数据库操作,后面还要添加很多进去
from pymongo import MongoClient,errors
from _datetime import datetime,timedelta
class mogo_queue():
def __init__(self,db,collection):
self.client = MongoClient()
self.database =self.client[db]#链接数据库
self.db = self.database[collection]#链接数据库里面这个表
def push_ip(self,ip,port,proxy):#把代理插进数据库的操作
try:
self.db.insert({'_id':ip,'port':port,'proxy':proxy})
print(proxy,'代理插入成功')
except errors.DuplicateKeyError as e:#对于重复的ip不能插入
print(proxy,'已经存在队列中')
def find_proxy(self):
proxy_list=[]#用来接收从数据库查找到的所有代理
for i in self.db.find():
proxy = i['proxy']
proxy_list.append(proxy)
return proxy_list
def delete_proxy(self,proxy):
self.db.remove({'proxy':proxy})
print(proxy,'无效代理删除成功')
这是主程序
import requests
from pymongo import MongoClient
from bs4 import BeautifulSoup
from mogodb_queue import mogo_queue
#ip_queue = mogo_queue('ip_database','proxy_collectipon')
class ip_catch(object):
ip_queue = mogo_queue('ip_database','proxy_collection')
def __init__(self,page=3):
self.page = 4
self.effective_ip_list=[]
self.url = 'http://ip.chinaz.com/getip.aspx'这是检验代理是否生效的网站,
简单来说就是用爬取到的ip访问这个网站,根据返回的数据判断
def proxy_catch(self ):
proxy_list=[]#接收爬到的代理
ip_url=['http://www.xicidaili.com/nn/{}'.format(str(i)) for i in range(self.page)]
header={
'User-Agent':"Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/535.24
(KHTML, like Gecko) Chrome/19.0.1055.1 Safari/535.24"
}
for url in ip_url:
data = requests.get(url,headers=header)
all_data=BeautifulSoup(data.text,'lxml')
all_ip = all_data.find_all('tr',class_= 'odd')
for i in all_ip:
ip= i.find_all('td')[1].get_text()#ip
port = i.find_all('td')[2].get_text()#端口
proxy= (ip+':'+port).strip()#组成成proxy代理
proxy_list.append(proxy)
return proxy_list
def catch_effictive_ip(self):
proxy_list=self.proxy_catch()
#ip_queue = mogo_queue('ip_database','proxy_collection')#链接数据库,把有用的代理插进去
for proxy in proxy_list:
try:
html = requests.get(self.url,proxies=proxy,timeout=1)#检验代理是否能正常使用
self.effective_ip_list.append(proxy)
print('网页返回状态码:',html, proxy,'代理有效')
ip= proxy.split(':')[0]#这是ip
port= proxy.split(':')[1]#这是端口
self.ip_queue.push_ip(ip,port,proxy)#将爬取到的代理插进数据库
#print(ip,port,proxy)
except:
print(proxy,'代理无效')
def test_proxy(self):
proxy_list=self.ip_queue.find_proxy()
for proxy in proxy_list:
try:
html = requests.get(self.url, proxies=proxy, timeout=1) # 检验代理是否能正常使用
self.effective_ip_list.append(proxy)
print('网页返回状态码:', html, proxy, '代理依然有效')
except:
self.ip_queue.delete_proxy(proxy)
#print(proxy, '该代理已经无效,删除处理')
def main_method(self):
self.test_proxy()#启用该主函数时,启动检验代理有效性,将无效的删除
#proxy_list = self.ip_queue.find_proxy()
print(proxy_list)#打印有效代理数量
while True:#循环到抓到所需要的数量为止,目前脚本还没完善,每次只抓取前面4页,
但是对于100个有效ip来说,肯定够用了,后续2.0再完善这个问题
proxy_list = self.ip_queue.find_proxy()
if len(proxy_list)>100:#设定当有用代理超过100时,无需爬取了,个人而言够用了
print('有用代理超过100,无需再爬取')
break
else :
print('有用代理少于100,需要重新爬取有用代理')
self.catch_effictive_ip()#m每次爬取的是默认前面4页
ip_list=ip_catch()
ip_list.main_method()#调用主函数,启动程序
这是运行结果
这是mogodb数据库里面的数据