MongoDB数据库免费代理获取

通过抓取代理到数据库,实现时时拥有100+可用的代理。

前面说到过,因为调试豆瓣的时候被豆瓣把自己的IP给封了,一直想搞个免费的代理IP,现在有时间了发个帖一下。这里基于上一篇文章的scrapy 学习,如果有意向了解的,可以移步:http://blog.csdn.net/weixin_39378885/article/details/78431566 。欢迎围观。
(一)保存到数据库

1,实现方法:
数据库: MongoDB
MongoDB简单使用,请参考: Python与MongoDB相关操作
爬虫手段: scrapy
全部实现方法,请参考: scrapy爬取西刺代理IP到Excel
主要通过在 scrapy中的 pipeline 中取处理 spider 获得的 IP,并保存到数据库。过程实现比较简单。需要注意的是: 数据库连接打开之后,切记要记得关闭!否则会导致端口占用严重

源代码:

from pymongo import MongoClient
import urllib.request

# 用来处理数据到数据库
class DbPipeline(object):
    # 连接DB数据库
    def connect_db(self):
        try:
            db = MongoClient("127.0.0.1",port=27017,)
            # databasenames = db.database_names()
            print("<connect_db> ---> 已连接数据库!")
            return db  # 返回对象
        except Exception as e:
            print("数据库连接失败 ! %s" %e)

    # 函数描述:检查IP是否可用
    # 传入参数:http or HTTPS, IP, port
    def filter_ip(self, item):
        #item = {1:{"kind":"http", "ip_address":"1275690842", "port":8888}}
        kind = item["kind"]
        ip = item["ip_address"]
        port = item["port"]  # port 为 int 型
        # print(_id,kind,ip,port)

        proxy = urllib.request.ProxyHandler({kind:"%s:%d"%(ip,port)})
        opener = urllib.request.build_opener(proxy)
        urllib.request.install_opener(opener)
        req = urllib.request.Request(url="http://www.baidu.com",headers={"User-Agent":generate_user_agent()})
        try:
            # 通过加载百度页面来判断IP是否可用
            response = urllib.request.urlopen(req,timeout=1)
            if response.code >= 200 and response.code <= 300:
                print("此IP可用! ",response.code)
                item["_id"] = ip
                #print(item)
                self.save_to_db(value=item)      # 这里必须使用dict(),不然会出错。因获得的item[row]是IPitem类型
            else:
                print("此IP不可用! 状态码:%s" %response.code)
                pass
        except Exception as e:
            print("此IP不可用! %s" %e)

    # 保存到数据库
    def save_to_db(self,value):
        db = self.connect_db()  #
        try:
            db_test_ip = db.test.IP     # 选择test数据库下的IP集合
            db_test_ip.save(value)
            db.close()
            print("完成操作,关闭数据库!")
        except Exception as e:
            db.close()
            print("出现异常,关闭数据库!")
            print(e)

    def process_item(self, item, spider):
        for each in item.values():      # 刚好获取需要的字典部分
            #print(each)
            self.filter_ip(dict(each))
        #for each in range(10):
            #threading.Thread(target=self.filter_ip(item),name="Mythread").start()
            #print("进程",each)

代码解读:

定义了一个类Dbpipeline来处理数据。
其中包含四个子函数:
①,connect_db: 用来连接数据库并返回一个数据库对象
②,filter_ip: 用来筛选出可用的数据库并保存到数据库
③,save_to_db: 用来供filter_ip调用。
④,process_item: 每一个继承自PIPELINE类必须调用的函数

详细解释,都在代码中。
样图

这里写图片描述

——————————————-分割线——————————————-

(二)从数据库中取可用的IP

源代码:

# coding = "utf-8"
import urllib.request
from user_agent.base import generate_user_agent
from pymongo import MongoClient
import random

class Get_ip():
    def __init__(self, number=1):
        self.number = number

    def connect_db(self):
        try:
            db = MongoClient(host="127.0.0.1", port=27017,)
            print("<connect_db> ---> 数据库连接成功!")
            return db
        except Exception as e:
            print("<connect_db> ---> 数据库连接失败,请检查地址是否正确! ",e)

    # 函数描述:从数据库随机获取一个IP,并检查其可用性
    # 函数返回:kind IP port (分别是 http或HTTPS, IP号, 端口号)
    def get_ip_from_db(self):
        db = self.connect_db()  # 获取实例化数据库对象
        try:
            db_test_ip = db.test.IP     # 选择IP集合
            ip_list = []
            for each in db_test_ip.find():      # Curser 对象必须通过遍历
                ip_list.append(each)
            ip_item = []
            for each in range(self.number):
                ip_item.append(random.choice(ip_list))  # 随机获取一个IP字典
            db.close()
            print("关闭数据库!")
            return db,ip_item
        except Exception as e:
            db.close()
            print("<get_ip_from_db> ---> 获取IP异常", "关闭数据库!",e)

    # 可以用返回该IP信息。包括 协议类型,IP地址,端口。
    # 不可用将其从数据库中删除
    def main(self):
        test_url = "http://www.baidu.com/"
        db,ip_item = self.get_ip_from_db()

        for each in ip_item:
            kind = each["kind"]
            ip = each["ip_address"]
            port = each["port"]
            try:
                Proxy = urllib.request.ProxyHandler({kind:"%s:%s"%(ip,port)})
                opener = urllib.request.build_opener(Proxy)
                urllib.request.install_opener(opener)

                head = {"User-Agent":generate_user_agent()}
                req = urllib.request.Request(url=test_url,headers=head,)
                response = urllib.request.urlopen(req, timeout=1)
                if response.code >= 200 and response.code <= 300:   # 可用的状态码范围
                    db.close()      # 即使关闭数据库,防止端口占用
                    yield kind,ip,port             # 返回地址信息的生成器
                else:
                    db_test_ip = db.test.IP  # 选择IP集合
                    db_test_ip.deleteOne(ip_item)   # 从数据库删除不可用IP
                    print("%s \n该IP不可用,已从数据库中删除!")
                    self.main()     # 再次取值
            except Exception as e:
                db.close()
                print("<main> ---> 出错啦! ",e)

# 返回一个包含IP信息的生成器
if __name__ == "__main__":
    number = int(input("********************** 欢迎使用免费IP获取脚本应用程序 ************************\n\t\t\t\t\t   请输入要获取IP的数量:"))
    test = Get_ip(number)
    generator = test.main()

    for each in generator:
        kind,ip,port = each
        print("IP地址为:%s//:%s:%s"%(kind,ip,port))

调试结果:

这里写图片描述

代码解读:

①,这里单独使用一个文件即可,毕竟只是从数据库中读取IP。
②,都是一些简单的数据库操作。具体请看代码中详解。
③,其他问题,可以参考以下。上面给的两个链接

To The End:

博主水平有限,代码也很简陋。如有什么问题跟意见,欢迎评论指出。感激不尽。

猜你喜欢

转载自blog.csdn.net/weixin_39378885/article/details/78471921
今日推荐