zoukankan      html  css  js  c++  java
  • python 使用 lru_cache 缓存代理IP

    本文地址:https://www.cnblogs.com/tujia/p/13690973.html

    背景:当我们用python写爬虫时,一般会用到代理IP;代理IP一般是有一定有效时间的,每次请求都换IP,有点浪费IP,所以我们需求在IP的有效时间内需要缓存IP,不换IP

    前提知识:

    1)@lru_cache 装饰器可以在程序运行期间缓存函数返回值,第一次调用函数缓存函数返回值,后面的调用就直接读缓存返回

    2)@lru_cache 装饰器会为被装饰的函数创建两个属性(方法):cache_info 和 cache_clear,其中 cache_clear 方法可以清除缓存,重新计算函数

    3)了解更多,请看官方文档:https://docs.python.org/zh-cn/3.7/library/functools.html#functools.lru_cache

    下面就直接上代码了,红色的地方是重点:

    import requests
    from bs4 import BeautifulSoup
    from functools import lru_cache
    
    
    # 获取代理ip(可以去芝麻代理注册一个账号,领取免费IP)
    # @link http://h.zhimaruanjian.com/getapi/
    @lru_cache(maxsize=1)
    def getProxies(retry_times=0):
        # 直连IP的api地址
        api_url = 'http://webapi.http.zhimacangku.com/getip?num=1&type=1&pro=&city=0&yys=0&port=1&pack=97108&ts=0&ys=0&cs=0&lb=1&sb=0&pb=4&mr=1&regions='
        # 请求头
        headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.83 Safari/537.36'}
        try:
            r = requests.get(api_url, headers=headers, timeout=3)
            if r.status_code == 200:
                if r.text.find('{') > -1:
                    j = r.json()
                    # 请x秒后再试
                    if j['code'] == 111:
                        s = int(re.search(r'd', j['msg']).group(0))
                        time.sleep(s)
                    # 套餐已用完
                    elif j['code'] == 121:
                        return None
                else:
                    proxyMeta = 'http://' + r.text.strip()
                    return {'http': proxyMeta, 'https': proxyMeta}
    
            if retry_times < 3:
                retry_times += 1
                return getProxies(retry_times)
        except requests.exceptions.RequestException:
            pass
    
        if retry_times < 3:
            retry_times += 1
            return getProxies(retry_times)
        else:
            return None
    
    
    # 获取网页内容
    def getContent(url, retry_times=0, use_proxy=True):
        headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.83 Safari/537.36'}
    
        try:
            proxies = getProxies() if use_proxy else None
            r = requests.get(url, headers=headers, proxies=proxies, timeout=10)
            if r.status_code == 200:
                r.encoding = 'utf-8'
                return r.text
        except requests.exceptions.InvalidProxyURL:
            print('InvalidProxyURL: %s' % str(proxies))
            # 代理异常,清除一下代理缓存,重新获取代理ip
            getProxies.cache_clear()
        except requests.exceptions.ProxyError:
            print('ProxyError: %s' % str(proxies))
            # 代理异常,清除一下代理缓存,重新获取代理ip
            getProxies.cache_clear()
        except requests.exceptions.InvalidURL:
            print('InvalidURL: %s %s' % (url, str(proxies)))
            # URL错误,也有可能是因为代理异常,所以也重新获取一个代理ip
            getProxies.cache_clear()
        except requests.exceptions.Timeout:
            print('TimeoutError: %s' % url)
        except requests.exceptions.RequestException:
            print('RequestException: %s' % url)
    
        # 代理异常或其他异常时
        if retry_times < 3:
            retry_times += 1
            return getContent(url, retry_times, use_proxy)
        else:
            return ''
    
    
    if __name__ == '__main__':
        for i in range(3):
            # 看一下三次打印的代理ip是不是一样的
            print(getProxies())
            # 请求一下百度试试
            content = getContent('https://www.baidu.com')
            if content != '':
                soup = BeautifulSoup(content, 'lxml')
                print(soup.title.string)
    
        print('Finished')

    本文地址:https://www.cnblogs.com/tujia/p/13690973.html


     完。

  • 相关阅读:
    Anaconda 和 Jupyter notebook
    DOM基础之创建元素
    python爬虫入门学习3 Requests请求库
    04 字典类型已内置方法
    05 流程控制
    03 可变类型与不可变类型
    02 元组数据类型
    01 列表内置方法
    day2笔记
    00 python基础知识
  • 原文地址:https://www.cnblogs.com/tujia/p/13690973.html
Copyright © 2011-2022 走看看