Python3自学 爬虫实战

初步构造代理池1.0版本

2017-01-15  本文已影响175人  蜗牛仔

这是第一次亲手尝试写代理池,之前在网站找了很多教程都没有看懂,于是按照自己的思路写一个简易版,目前这个是雏形,后面要加进多线程来检验IP以及通过更多的代理网站来爬取有效IP,该脚本主要思路是启动程序时,会自动测试数据库里面的ip,如果有效ip少于一定数目,会进行重新爬取有效ip,然后入库,如果数量足够,则不进行爬取
这次用到的代理网站是http://www.xicidaili.com/nn/

SLC`4UQNW0U0OVA~71CRVLC.png

这是封装的数据库操作,后面还要添加很多进去

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()#调用主函数,启动程序

这是运行结果

Paste_Image.png

这是mogodb数据库里面的数据

Paste_Image.png
上一篇下一篇

猜你喜欢

热点阅读