Python读取配置文件-ConfigParser的二次封装方法
作者:guoqianqian5812 发布时间:2023-06-15 09:19:58
标签:Python,配置文件,ConfigParser,封装
Python读取配置文件-ConfigParser二次封装
直接上上代码
test.conf
[database]
connect = mysql
sleep = no
test = yes
config.py
# -*- coding:utf-8 -*-
__author__ = 'guoqianqian'
import os
import ConfigParser
import os
current_dir = os.path.abspath(os.path.dirname(__file__))
class OperationalError(Exception):
"""operation error."""
class Dictionary(dict):
""" custom dict."""
def __getattr__(self, key):
return self.get(key, None)
__setattr__ = dict.__setitem__
__delattr__ = dict.__delitem__
class Config:
def __init__(self, file_name="test", cfg=None):
"""
@param file_name: file name without extension.
@param cfg: configuration file path.
"""
env = {}
for key, value in os.environ.items():
if key.startswith("TEST_"):
env[key] = value
config = ConfigParser.ConfigParser(env)
if cfg:
config.read(cfg)
else:
config.read(os.path.join(current_dir, "conf", "%s.conf" % file_name))
for section in config.sections():
setattr(self, section, Dictionary())
for name, raw_value in config.items(section):
try:
# Ugly fix to avoid '0' and '1' to be parsed as a
# boolean value.
# We raise an exception to goto fail^w parse it
# as integer.
if config.get(section, name) in ["0", "1"]:
raise ValueError
value = config.getboolean(section, name)
except ValueError:
try:
value = config.getint(section, name)
except ValueError:
value = config.get(section, name)
setattr(getattr(self, section), name, value)
def get(self, section):
"""Get option.
@param section: section to fetch.
@return: option value.
"""
try:
return getattr(self, section)
except AttributeError as e:
raise OperationalError("Option %s is not found in "
"configuration, error: %s" %
(section, e))
if __name__ == "__main__":
conf = Config()
print conf.get("database").connect
print conf.get("database").sleep
print conf.get("database").test
执行结果
mysql
False
True
目录结构
demo
conf
test.conf
config.py
读取配置文件&&简单封装
之前有做过把爬虫数据写到数据库中的练习,这次想把数据库信息抽离到一个ini配置文件中,这样做的好处在于可以在配置文件中添加多个数据库,方便切换(另外配置文件也可以添加诸如邮箱、url等信息)
1.configparser模块
python使用自带的configparser模块用来读取配置文件,配置文件的形式类似windows中的ini文件
在使用前需要先安装该模块,使用pip安装即可
2.configparser读取文件的基本方法
(1)新建一个config.ini文件,如下
(2)新建一个readconfig.py文件,读取配置文件的信息
import configparser
cf = configparser.ConfigParser()
cf.read("E:\Crawler\config.ini") # 读取配置文件,如果写文件的绝对路径,就可以不用os模块
secs = cf.sections() # 获取文件中所有的section(一个配置文件中可以有多个配置,如数据库相关的配置,邮箱相关的配置, 每个section由[]包裹,即[section]),并以列表的形式返回
print(secs)
options = cf.options("Mysql-Database") # 获取某个section名为Mysql-Database所对应的键
print(options)
items = cf.items("Mysql-Database") # 获取section名为Mysql-Database所对应的全部键值对
print(items)
host = cf.get("Mysql-Database", "host") # 获取[Mysql-Database]中host对应的值
print(host)
上述代码运行结果如下,可以和config.ini进行对比
3.引入os模块,使用相对目录读取配置文件
工程目录如下:
readconfig.py:
import configparser
import os
root_dir = os.path.dirname(os.path.abspath('.')) # 获取当前文件所在目录的上一级目录,即项目所在目录E:\Crawler
cf = configparser.ConfigParser()
cf.read(root_dir+"/config.ini") # 拼接得到config.ini文件的路径,直接使用
secs = cf.sections() # 获取文件中所有的section(一个配置文件中可以有多个配置,如数据库相关的配置,邮箱相关的配置,每个section由[]包裹,即[section]),并以列表的形式返回
print(secs)
options = cf.options("Mysql-Database") # 获取某个section名为Mysql-Database所对应的键
print(options)
items = cf.items("Mysql-Database") # 获取section名为Mysql-Database所对应的全部键值对
print(items)
host = cf.get("Mysql-Database", "host") # 获取[Mysql-Database]中host对应的值
print(host)
或者使用os.path.join()进行拼接
import configparser
import os
root_dir = os.path.dirname(os.path.abspath('.')) # 获取当前文件所在目录的上一级目录,即项目所在目录E:\Crawler
configpath = os.path.join(root_dir, "config.ini")
cf = configparser.ConfigParser()
cf.read(configpath) # 读取配置文件
secs = cf.sections() # 获取文件中所有的section(一个配置文件中可以有多个配置,如数据库相关的配置,邮箱相关的配置,每个section由[]包裹,即[section]),并以列表的形式返回
print(secs)
options = cf.options("Mysql-Database") # 获取某个section名为Mysql-Database所对应的键
print(options)
items = cf.items("Mysql-Database") # 获取section名为Mysql-Database所对应的全部键值对
print(items)
host = cf.get("Mysql-Database", "host") # 获取[Mysql-Database]中host对应的值
print(host)
4.通过读取配置文件
重新写一下之前的requests+正则表达式爬取猫眼电影的例子
把读取配置文件readconfig.py和操作数据库handleDB.py分别封装到一个类中
readconfig.py如下
import configparser
import os
class ReadConfig:
"""定义一个读取配置文件的类"""
def __init__(self, filepath=None):
if filepath:
configpath = filepath
else:
root_dir = os.path.dirname(os.path.abspath('.'))
configpath = os.path.join(root_dir, "config.ini")
self.cf = configparser.ConfigParser()
self.cf.read(configpath)
def get_db(self, param):
value = self.cf.get("Mysql-Database", param)
return value
if __name__ == '__main__':
test = ReadConfig()
t = test.get_db("host")
print(t)
handleDB.py如下
# coding: utf-8
# author: hmk
from common.readconfig import ReadConfig
import pymysql.cursors
class HandleMysql:
def __init__(self):
self.data = ReadConfig()
def conn_mysql(self):
"""连接数据库"""
host = self.data.get_db("host")
user = self.data.get_db("user")
password = self.data.get_db("password")
db = self.data.get_db("db")
charset = self.data.get_db("charset")
self.conn = pymysql.connect(host=host, user=user, password=password, db=db, charset=charset)
self.cur = self.conn.cursor()
def execute_sql(self, sql, data):
"""执行操作数据的相关sql"""
self.conn_mysql()
self.cur.execute(sql, data)
self.conn.commit()
def search(self, sql):
"""执行查询sql"""
self.conn_mysql()
self.cur.execute(sql)
return self.cur.fetchall()
def close_mysql(self):
"""关闭数据库连接"""
self.cur.close()
self.conn.close()
if __name__ == '__main__':
test = HandleMysql()
sql = "select * from maoyan_movie"
for i in test.search(sql):
print(i)
最后的运行文件,调用前面的方法
# coding: utf-8
# author: hmk
import requests
import re
from common import handleDB
class Crawler:
"""定义一个爬虫类"""
def __init__(self):
self.db = handleDB.HandleMysql()
@staticmethod
def get_html(url, header):
response = requests.get(url=url, headers=header)
if response.status_code == 200:
return response.text
else:
return None
@staticmethod
def get_data(html, list_data):
pattern = re.compile(r'<dd>.*?<i.*?>(\d+)</i>.*?' # 匹配电影排名
r'<p class="name"><a.*?data-val=".*?">(.*?)' # 匹配电影名称
r'</a>.*?<p.*?class="releasetime">(.*?)</p>' # 匹配上映时间
r'.*?<i.*?"integer">(.*?)</i>' # 匹配分数的整数位
r'.*?<i.*?"fraction">(.*?)</i>.*?</dd>', re.S) # 匹配分数小数位
m = pattern.findall(html)
for i in m: # 因为匹配到的所有结果会以列表形式返回,每部电影信息以元组形式保存,所以可以迭代处理每组电影信息
ranking = i[0] # 提取一组电影信息中的排名
movie = i[1] # 提取一组电影信息中的名称
release_time = i[2] # 提取一组电影信息中的上映时间
score = i[3] + i[4] # 提取一组电影信息中的分数,这里把分数的整数部分和小数部分拼在一起
list_data.append([ranking, movie, release_time, score]) # 每提取一组电影信息就放到一个列表中,同时追加到一个大列表里,这样最后得到的大列表就包含所有电影信息
def write_data(self, sql, data):
self.db.conn_mysql()
try:
self.db.execute_sql(sql, data)
print('导入成功')
except:
print('导入失败')
self.db.close_mysql()
def run_main(self):
start_url = 'http://maoyan.com/board/4'
depth = 10 # 爬取深度(翻页)
header = {"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
"Accept-Encoding": "gzip, deflate, sdch",
"Accept-Language": "zh-CN,zh;q=0.8",
"Cache-Control": "max-age=0",
"Connection": "keep-alive",
"Host": "maoyan.com",
"Referer": "http://maoyan.com/board",
"Upgrade-Insecure-Requests": "1",
"User-Agent": "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.75 Safari/537.36"}
for i in range(depth):
url = start_url + '?offset=' + str(10 * i)
html = self.get_html(url, header)
list_data = []
self.get_data(html, list_data)
for i in list_data:
"""这里的list_data参数是指正则匹配并处理后的列表数据(是一个大列表,包含所有电影信息,每个电影信息都存在各自的一个列表中;
对大列表进行迭代,提取每组电影信息,这样提取到的每组电影信息都是一个小列表,然后就可以把每组电影信息写入数据库了)"""
movie = i # 每组电影信息,这里可以看做是准备插入数据库的每组电影数据
sql = "insert into maoyan_movie(ranking,movie,release_time,score) values(%s, %s, %s, %s)" # sql插入语句
self.write_data(sql, movie)
if __name__ == '__main__':
test = Crawler()
test.run_main()
来源:https://blog.csdn.net/guoqianqian5812/article/details/68610760
0
投稿
猜你喜欢
- 一、可以使用以下步骤获取两个以逗号分割的字符串的并集:使用explode函数将两个字符串转换为数组,以便可以对其执行操作。使用array_m
- 内容摘要:浏览器不兼容这个难题,一直是网页设计师们头痛的事情。ie7.0的面世,尚且不论他是否较之ie6.0进步, ie7和ie6
- 隐藏并修改文件的最后修改时间的asp-webshell。源码:<% '隐藏并修改文件的最后修改时间的aspshell '
- MySQL由于它本身的小巧和操作的高效, 在数据库应用中越来越多的被采用.我在开发一个P2P应用的时候曾经使用MySQL来保存P2P节点,由
- /* --注意:准备数据(可略过,非常耗时) CREATE TABLE CHECK1_T1 ( ID INT, C1 CHAR(8000)
- W3C 发布 XPath 1.0 规范是在 1999 年,那时我还正在备战高考,不料十年后,我才开始学习XPath,落后的差距不是一般的大(
- 如题:我写入关键字到数据库,多的时候用|隔开了,我提取再做相关文章搜索的时候,我怎么提取用|隔开的文字啊,这样我就好用关键字做搜索啊 回复:
- 之前在懒懒分会上分享的一点关于border画小图的内容, 完整的ppt在这里.原理css盒模型一个盒子包括: margin+border+p
- 近段时间由于修改一个ASP程序(有SQL注入漏洞),在网上找了很多相关的一些防范办法,都不近人意,所以我将现在网上的一些方法综合改良了一下,
- 先下载:http://signup.qq.com/js/a.js用 IntelliJ IDEA 格式化代码:var naa = true;O
- 我设了个排卖的起始时间然后设了一个结束时间现在要精确到小时比如提示 “离到期时间:1天XX小时”大家有什么想法吗?我就是在小时总是不能实现,
- MySQL支持大量的列类型,它可以被分为3类:数字类型、日期和时间类型以及字符串(字符)类型。本节首先给出可用类型的一个概述,并且总结每个列
- 首先来看,ASP读取ACCESS数据库。代码如下:<% @language="VBScript"&nbs
- 我和朋友对此的看法有分歧,我明明记得有不需要返回的时候的?你的看法是对的,例如在表中删除记录。我们来看看下面的例子——在Employee表中
- 原文:http://research.microsoft.com/~helenw/papers/subspace.pdfwindow.nam
- Liwu_Items表,CreateTime列建立聚集索引 第一种,sqlserver2005特有的分页语法 代码如下:declare @p
- 一、事件捕捉(Event Capture)的实现问题首先在说这件事前,先感谢一下Realazy。 W3C DOM Level2的事
- 在我转到wordpress之后第一个考虑的是它的数据库备份恢复问题,因为写bloger都知道,自己的blog记录的都是自己需要的宝贵的资料和
- -crop参数是从一个图片截取一个指定区域的子图片.格式如下:convert -crop widthxheight{+-
- 为了降低用户注册难度,国际站的主注册表单一直在改进。主注册三月至今发生了两次较大的变化,现在对表单调整的地方分解如下:1. 两步