code: def scan(self,
               proxy_scanner,
               expected_num=20,
               val_thr_num=4,
               queue_timeout=3,
               val_timeout=5,
               out_file='proxies.json'):
          
          try:
              proxy_scanner.scan()
              self.logger.info('starting {} threads to validating proxies...'
                               .format(val_thr_num))
              val_threads = []
              for i in range(val_thr_num):
                  t = threading.Thread(
                      name='val-{:0>2d}'.format(i + 1),
                      target=self.validate,
                      kwargs=dict(
                          proxy_scanner=proxy_scanner,
                          expected_num=expected_num,
                          queue_timeout=queue_timeout,
                          val_timeout=val_timeout))
                  t.daemon = True
                  val_threads.append(t)
                  t.start()
              for t in val_threads:
                  t.join()
              self.logger.info('Proxy scanning done!')
          except:
              raise
          finally:
              if out_file is not None:
                  self.save(out_file)
docs: Scan and validate proxies
  
          Firstly, call the `scan` method of `proxy_scanner`, then using multiple
          threads to validate them.
  
          Args:
              proxy_scanner: A ProxyScanner object.
              expected_num: Max number of valid proxies to be scanned.
              val_thr_num: Number of threads used for validating proxies.
              queue_timeout: Timeout for getting a proxy from the queue.
              val_timeout: An integer passed to `is_valid` as argument `timeout`.
              out_file: A string or None. If not None, the proxies will be saved
                        into `out_file`.