笔记11 代理池

 笔记10
 
 1,代理池
 2,scrapy 文件下载,图片下载
 3,ajax--qq
 进程--线程--协程:
   例子:11洗衣房--10台洗衣机--有一个洗衣工
   进程   协程    一个线程
   
   进程>线程>协程
  async关键字----开启异步方法
  
  def b():
    1
	2---等待--整个线程都是等待
	3
  b()---这个方法不是异步方法,所以执行的过程中不会等待。
  async a():---这个方法就是一个异步方法。
    1
	2 ---等待--请求的时候,等待响应---异步方法就会在这里挂起,去执行别的方法
	3
 await  --等待(让挂起)--等待的终止条件
 
 
 
 
 
 
 
 代理池应用


db----->第一步
redis----list实现

list如何来设计? 如何保证从list中获取的代理是最新的?
 1,从尾部插入最新的可用的代理。
 2,代理池数量很多的时候,代理池中之前验证的代理还需要继续验证(有可能失效),每次从头部取出一片(一半),在重新验证,可用的在放在尾部。
 3,将来从代理池选取代理使用的时候,只需要从尾部获取一个最新最可用的即可
 
 第二步 getter--#去网上爬取免费代理-->Internet
 
 添加器 + 校验器--》db
   
 第三步 校验器---1,实现一个对外的入口,校验的方法都是私有的,不能对外开放。这个入口就相当于一个篮子,只需要向里面放代理,校验器就可以自动从里面获取来校验。
 2,真正的添加逻辑,就是在校验成功的时候才添加的。--校验的同时,也是添加。
 3,代理的有效验证是消耗时间的,不能用同步请求来做,效率非常差--异步请求
 
 第四步
 添加器--1,判断代理池是否达到上限和下限。当上限达到,停止添加,当下限达到,开始添加
 2,添加器主要调用校验来校验的同时添加
 
 代码
 import redis
 from proxypool.settings import PASSWORD,HOST,PORT
 class Redis_Client(object):
    #设置密码选择功能
    def __init__(self,host=HOST):
	#判断是否有密码:
	if PASSWORD:
	  self._db=redis.Redis(host=host,port=port,password=PASSWORD)
	else:
	  self._db=redis.Redis(host=host,port=port)
	  
	#将代理添加到代理池的尾部
	def put(self,proxy):
	  self._db.rpush(PROXIES,proxy)
	#将头部获取count这个代理,并将其删除
	def get(self,count=1):
	  #lrange:获取指定范围的内容
	  #ltrim:保留指定范围内的内容,其他删除
	    proxies=self._db.lrange(PROXIES,0,count-1)
		self._db.ltrim(PROXIES,count,-1)
		return proxies
	#从尾部获取一个最新代理
	def pop(self):
	    #从redis中获取来的数据是bytes类型
	    return self._db.rpop(PROXIES).decode('utf-8')
	#计算代理池长度
	@property
	def queue_len(self):
	    return self._db.lien(PROXIES)
	def flush(self):
	    self._db.flushall()#清空所有

if __name__='__main__':
  r=Redis_Client()
  print(r.queue_len) 
  
	cmd中复习
	redis-cli
	lrange proxies 0 5 
	ltrim proxies 6 -1
	lrange proxies 0 -1
	
	
	
	  
	
配置文件(密码)
创建setting
#密码:如果为空,就没有密码
PASSWORD = ''
#主机ip和端口号
HOST = 'localhost'
PORT = 6379

#代理池的名称
PROXIES = 'proxies'
#测试代理的网址
TSET_API = 'https://www.baidu.com/'
#配置测试网址的请求头
TEST_REQUEST_HEADERS = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.79 Safari/537.36',
}
#测试代理的超时时间
TSET_TIME_OUT = 30


第二步 
getter中

class ProxyGetter(object):
   #爬取代理方法,名称统一为crawl
   def crawl_66ip(self):
     
第三步 
Scheduler中
import aiohttp
from Requests01.proxypool.settings import TSET_API,TEST_REQUEST_HEADERS,TSET_TIME_OUT
import asyncio
from Requests01.proxypool.db import Reids_Client
class VaildityTester(object):
    def __init__(self):
        #篮子
        self._raw_proxies = []

    #向篮子放东西
    def set_raw_proxies(self,proxies):
        self._raw_proxies = proxies
        # 数据的所有连接,用的时候在创建。
        self._conn = Reids_Client()
    #校验代理,要使用异步 请求
    async def test_single_proxy(self,proxy):
        try:
            # 创建一个session对象
            async with aiohttp.ClientSession() as session:
                # 参数校验,如果proxy参数是一个bytes类型,就给他转成字符串
                if isinstance(proxy, bytes):
                    proxy = proxy.decode('utf-8')
                real_proxy = 'http://' + proxy
                try:
                    async with session.get(TSET_API,
                                           headers=TEST_REQUEST_HEADERS,
                                           proxy=real_proxy,
                                           timeout=TSET_TIME_OUT) as response:
                        if response.status == 200:
                            # 该代理可用
                            # 添加到代理池
                            self._conn.put(proxy)
                            print('有效代理!', proxy)
                except Exception:
                    print('无效代理!',proxy)
        except Exception as e:
            print(e)
      def test(self):
	    print('代理池开始启动!')
	  #创建一个loop(任务执行链)
	  loop=asyncio.get_event_loop()
	  #执行任务
	  tasks=[self.test_single_proxy(proxy)for proxy in self._raw_proxies]
	  #启动loop ---循环链
	  loop.run_until_complete(asyncio.wait(tasks))
第四步
#添加器
class PoolAdder(object):
  #threshold--阀值--代理池最大值
  def __init__(self,threshold): 
	 self.threshold=threshold
	 #校验
	 self._tester=VaildityTester()
	 #db
	 self._conn=Redis_Client()
	 self._crawler=FreeProxyGetter()
  #判断代理池数量是否达到最大值
  def is_over_threshold(self):
    """
	:return: True:达到 False不能
	"""
	if self._conn.queue_len>=self._theshold:
	  return True
  #添加代理到代理池的方法
  def add_to_queue(self):
    #代理的获取是从getter组件中获取的
	print('添加器开始工作……')
	while True:
	  #当添加到代理池达到最大值就不添加了
	  if self.is_over_threshold():
         break
		 
	  #1、先从网上获取免费代理
	  #问题:现在只能调用单一的爬取代理的方法,无法从各个网站都获取代理
	  #如何实现?
	  proxies=self._crawler.crawl_ip3366()
	  #proxies=self._crawler.crawl_66ip()
	  #2、用校验器校验(校验的同时在添加)
	  
	  #2.1先把代理放到篮子
	  self._tester.set_raw_proxies(proxies)
	  #2.2test方法就自动从篮子中获取代理校验
	  self._tester.test()
	  
		 
		 
		 
		 
		 
demo_with中
import requests
response=requests.get('https://www.baidu.com/')

with requests.get('https://www.baidu.com/')as response:
  print(response.text)
print(response.status_code)  

一、元类
1,什么是类?
类是一个对象,可以创建对象的对象就是类。
object=class()
2,什么是元类?
可以创建类的对象就是元类。
class=metaclass()
object=class()
3,python提供了用class方法来创建类。
也提供了一个元类,我们可以通过这个元类来自定义类。–这个类就叫做type
type(
类的名字
(,),类的继承
{,}类的属性
)–>class
4,一个对象在创建的时候,如果想要让这个对象包含一些内容。
new
init

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值