Esempio n. 1
0
    def test_ips(self, ips_list):
        """
        测试爬取到的 IP 是否可用
        """
        timeout = urllib3.Timeout(connect=3, read=6)
        for ip in ips_list:
            # 将暂时可用的IP保存至 ips_ok.txt
            file = open(self.config["abs_dir"]+"/ips_ok.txt", "at")
            try:
                manager = urllib3.ProxyManager(ip, cert_reqs="CERT_REQUIRED", ca_certs=certifi.where(),
                                               timeout=timeout,)
                rep = manager.request("GET", self.config["test_domain"])
                # 如果 response headers 的状态码为 200,则说明此 IP 可用
                if rep.status == 200:
                    self.ip_ok_lib.append(ip)
                    file.write(ip+"\n")
                    print("Test success and saved ip: {0}".format(ip))
            # retry 次数过多则抛出此异常
            except urllib3.exceptions.MaxRetryError:
                print("{0} Test failed ".format(ip))
            # 处理其他未知异常
            except Exception as e:
                print("Problems :{0}".format(e))
            finally:
                file.close()

        toolBox.print_format("Test finished {0}")
        toolBox.count_ip(self.config["abs_dir"])
Esempio n. 2
0
 def connect_test(self):
     """
     测试要爬取的目标网站 此时 是否可用
     """
     manager = self.manager
     # 暂时支持以下三个网站,后续更新添加
     # key 为目标网站在IPReaper类中的方法名称,以供后续 eval()
     base_ip_com = {"get_xici_ips": "http://www.xicidaili.com/",
                    "get_66_ips": "http://www.66ip.cn/",
                    "get_kuai_ips": "http://www.kuaidaili.com/"}
     # 存储 此时 可爬去的 IP 网站
     self.ok_com = []
     toolBox.print_format("Connection test")
     for name, url in base_ip_com.items():
         # 对同一网站重复 3 次请求(实际上 urllib3 中的 request 已经有 retry 次数)
         # 以后会对此问题进行优化
         for n in range(3):
             print("{0}th url:{1}".format(n+1, url))
             try:
                 rep = manager.request("GET", url)
                 if rep.status == 200:
                     # 状态码为 200,则测试成功,此网站可用
                     self.ok_com.append((name, url))
                     print("success")
                     break
             except urllib3.exceptions.MaxRetryError:
                 print("fail")
     toolBox.print_format("Test finished")
Esempio n. 3
0
 def generate_ips(self):
     """
     从文件中读取 ip ,以生成器的方式返回可用 ip
     """
     path = self.config["abs_dir"] + "/ips_ok.txt"
     with open(path, "rt") as ips_file:
         for ip in ips_file:
             yield toolBox.strip(ip)
Esempio n. 4
0
 def run_reaper(self):
     """
     运行 reaper 爬虫
     """
     # 存储添加了可爬取网站对应方法的协程
     func_list = []
     for (func_name, domain_url) in self.ok_com:
         # 通过 eval() 将字符串的方法名 转换为 方法对象
         func = eval("self."+func_name)
         # 使用协程
         func_list.append(gevent.spawn(func))
         print("function {0} is ready: {1}".format(func_name, domain_url))
     toolBox.print_format("IPReaper running")
     print("IPReaper is getting proxy IPs......")
     print("......")
     print("...")
     print(".")
     # 将所有协程 join 并 运行
     gevent.joinall(func_list)
Esempio n. 5
0
 def get_ips_from_file(self):
     """
     从 ips_ok.txt 中读取可用 ip
     :return: 存储可用 ip 的列表
     """
     path = self.config["abs_dir"] + "/ips_ok.txt"
     ips_ok = []
     with open(path, "rt") as ips_file:
         for ip in ips_file:
             ip = toolBox.strip(ip)
             ips_ok.append(ip)
     return ips_ok
Esempio n. 6
0
    def load_config():
        """
        读取加载文件:同级目录下的 config.txt
        并赋值给类属性 config,以供其他方法共享、调用
        """
        config = {}

        # 读取配置文件中的参数的类型是字符串,但以下参数值得类型不应该是字符串
        # 所以构建此列表,以供后续处理其中对应的值
        need_eval = ["proxy", "connect_timeout", "read_timeout", "frequency"]
        config_file = os.path.abspath("config.txt")
        with open(config_file, "rt") as config_file:
            for item in config_file:
                item = toolBox.strip(item)
                key, value = item.split("=")
                if value == "":
                    msg = "'" + key + "'"
                    # 如果只获取到了 key 而没有获取到对应 value,则抛出解析错误异常
                    raise AnalysisError(msg)
                # 将字符串值转换为相应类型
                config[key] = eval(value) if key in need_eval else value
        toolBox.print_format("Loading config")

        # 设置各可配置项的默认值
        config.setdefault("proxy", False)
        config.setdefault("dir_name", "ips_lib/")
        config.setdefault("abs_dir", os.path.abspath(config["dir_name"]))

        # 暂时只支持 html.parser,后续加入 lxml 等解析器
        config.setdefault("parser", "html.parser")
        config.setdefault("connect_timeout", 3)
        config.setdefault("read_timeout", 6)
        config.setdefault("frequency", 6)
        config.setdefault("test_domain", "https://book.douban.com/")
        toolBox.print_dict(config)
        return config
Esempio n. 7
0
    def get_66_ips(self):
        """
         获取 66网站 的 IP
        """
        base_url = ["http://www.66ip.cn/nmtq.php?proxytype=0",  # http
                    "http://www.66ip.cn/nmtq.php?proxytype=1"]  # https

        for n in range(10):
            url = random.choice(base_url)
            html = self.get_html(url, "gbk")
            tag = list(islice(html, 10, 49))[0::2]
            pre = "http://" if url.endswith("0") else "https://"
            for t in tag:
                if t is None:
                    continue
                ip_path = pre + toolBox.strip(t)
                self._ip_cache_lib.add(ip_path)
            time.sleep(self.config["frequency"])