牛骨文教育服务平台(让学习变的简单)
博文笔记

爬虫常用代码--基础爬虫(含代理和日志)

创建时间:2018-10-19 投稿人: 浏览次数:402


import logging
import sys
import urllib.request
import random
import ssl
# 全局取消安全证书验证,如果没有这一句会报错
ssl._create_default_https_context = ssl._create_unverified_context

# 创建日志基本上就是这个套路
# 创建实例,参数为日志文件名
logger = logging.getLogger("basicspider")

# 定义日志的格式,参数分别为:时间,异常登记

formatter = logging.Formatter("%(asctime)s %(levelname)s %(message)s")

# 开始创建日志:文件日志,终端日志
# 创建文件日志
file_handler = logging.FileHandler("basicspider.log")
# 设置文件日志格式
file_handler.setFormatter(formatter)

# 创建终端日志

consle_handler = logging.StreamHandler(sys.stdout)
consle_handler.setFormatter(formatter)

# 设置日志默认级别,比这个级别高的错误都会写进来。10是debug,20是INFO,30是WARNING,40是ERROR,50是FATAL
# 一般来说,调试的时候设置为debug,但是发布的时候最好设置到error,否则会显得很外行
logger.setLevel(logging.INFO)

# 把文件日志和终端日志添加到日志处理器中

logger.addHandler(file_handler)
logger.addHandler(consle_handler)
# 以上建立日志过程结束
PROXY_RANGE_MIN = 1
PROXY_RANGE_MAX = 10
PROXY_RANGE_NUM = 11
NUMRETRIES = 10
TIMEOUT = 10


def downloadHtml(url, headers=[], proxy={}, num_retries=10, timeout=10, decodeInfo="utf-8"):
    """爬虫的get请求,考虑了UA等http request head部分的设置
    支持代理服务器处理
    如果返回的状态码不是200的处理方式
    考虑了超时问题和网页编码格式
    """
    #logger.debug("download start")
    # 一般来说使用UA池和代理服务器池访问页面会不容易被反爬
    # 动态的调整代理服务器的使用策略
    html = None  # z最终返回值是一个html,在这里设置一个初始值,这样一定可以返回
    if num_retries <= 0:
        return html
    if random.randint(PROXY_RANGE_MIN, PROXY_RANGE_MAX) >= PROXY_RANGE_NUM:  # 70%概率不使用代理服务器
        logger.info("No Proxy")
        proxy = None
    else:
        logger.info("Already Use Proxy")

    proxy_handler = urllib.request.ProxyHandler(proxy)
    #logger.debug("download completed")
    opener = urllib.request.build_opener(proxy_handler)
    opener.addheaders = headers
    urllib.request.install_opener(opener)
    try:
        response = urllib.request.urlopen(url)
        html = response.read().decode(decodeInfo)
    except UnicodeDecodeError as u:
        logger.error("UnicodeDecodeError:", u)
    except urllib.error.URLError or urllib.error.HTTPError as e:
        logger.error("urllib error:", e)
        if hasattr(e, "code") and 400 <= e.code < 500:
            logger.error("Client Error")
        elif hasattr(e, "code") and 500 <= e.code < 600:
            html = downloadHtml(url, headers, proxy, timeout,
                                decodeInfo, num_retries-1)
            logger.error("Server Error")
    except:
        logger.error("Download Error")

    return html


if __name__ == "__main__":
    url = "http://www.baidu.com"
    headers = [("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36")]
    proxy = {"http": "106.75.164.15:3128"}
    print(downloadHtml(url, headers, proxy, NUMRETRIES, TIMEOUT))
    # 注意 日志remove必须在外边,保证可以remove
logger.removeHandler(file_handler)
logger.removeHandler(consle_handler)

声明:该文观点仅代表作者本人,牛骨文系教育信息发布平台,牛骨文仅提供信息存储空间服务。