爬虫常用代码--基础爬虫(含代理和日志)
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)
声明:该文观点仅代表作者本人,牛骨文系教育信息发布平台,牛骨文仅提供信息存储空间服务。