網(wǎng)站首頁(yè) 編程語(yǔ)言 正文
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
執(zhí)行結(jié)果
mysql
False
True
目錄結(jié)構(gòu)
demo ? ? conf ? ? ? ? test.conf ? ? config.py
讀取配置文件&&簡(jiǎn)單封裝
之前有做過(guò)把爬蟲(chóng)數(shù)據(jù)寫(xiě)到數(shù)據(jù)庫(kù)中的練習(xí),這次想把數(shù)據(jù)庫(kù)信息抽離到一個(gè)ini配置文件中,這樣做的好處在于可以在配置文件中添加多個(gè)數(shù)據(jù)庫(kù),方便切換(另外配置文件也可以添加諸如郵箱、url等信息)
1.configparser模塊
python使用自帶的configparser模塊用來(lái)讀取配置文件,配置文件的形式類似windows中的ini文件
在使用前需要先安裝該模塊,使用pip安裝即可
2.configparser讀取文件的基本方法
(1)新建一個(gè)config.ini文件,如下
(2)新建一個(gè)readconfig.py文件,讀取配置文件的信息
import configparser cf = configparser.ConfigParser() cf.read("E:\Crawler\config.ini") # 讀取配置文件,如果寫(xiě)文件的絕對(duì)路徑,就可以不用os模塊 secs = cf.sections() # 獲取文件中所有的section(一個(gè)配置文件中可以有多個(gè)配置,如數(shù)據(jù)庫(kù)相關(guān)的配置,郵箱相關(guān)的配置, 每個(gè)section由[]包裹,即[section]),并以列表的形式返回 print(secs) options = cf.options("Mysql-Database") # 獲取某個(gè)section名為Mysql-Database所對(duì)應(yīng)的鍵 print(options) items = cf.items("Mysql-Database") # 獲取section名為Mysql-Database所對(duì)應(yīng)的全部鍵值對(duì) print(items) host = cf.get("Mysql-Database", "host") # 獲取[Mysql-Database]中host對(duì)應(yīng)的值 print(host)
上述代碼運(yùn)行結(jié)果如下,可以和config.ini進(jìn)行對(duì)比
3.引入os模塊,使用相對(duì)目錄讀取配置文件
工程目錄如下:
readconfig.py:
import configparser import os root_dir = os.path.dirname(os.path.abspath('.')) # 獲取當(dāng)前文件所在目錄的上一級(jí)目錄,即項(xiàng)目所在目錄E:\Crawler cf = configparser.ConfigParser() cf.read(root_dir+"/config.ini") # 拼接得到config.ini文件的路徑,直接使用 secs = cf.sections() # 獲取文件中所有的section(一個(gè)配置文件中可以有多個(gè)配置,如數(shù)據(jù)庫(kù)相關(guān)的配置,郵箱相關(guān)的配置,每個(gè)section由[]包裹,即[section]),并以列表的形式返回 print(secs) options = cf.options("Mysql-Database") # 獲取某個(gè)section名為Mysql-Database所對(duì)應(yīng)的鍵 print(options) items = cf.items("Mysql-Database") # 獲取section名為Mysql-Database所對(duì)應(yīng)的全部鍵值對(duì) print(items) host = cf.get("Mysql-Database", "host") # 獲取[Mysql-Database]中host對(duì)應(yīng)的值 print(host)
或者使用os.path.join()進(jìn)行拼接
import configparser import os root_dir = os.path.dirname(os.path.abspath('.')) # 獲取當(dāng)前文件所在目錄的上一級(jí)目錄,即項(xiàng)目所在目錄E:\Crawler configpath = os.path.join(root_dir, "config.ini") cf = configparser.ConfigParser() cf.read(configpath) # 讀取配置文件 secs = cf.sections() # 獲取文件中所有的section(一個(gè)配置文件中可以有多個(gè)配置,如數(shù)據(jù)庫(kù)相關(guān)的配置,郵箱相關(guān)的配置,每個(gè)section由[]包裹,即[section]),并以列表的形式返回 print(secs) options = cf.options("Mysql-Database") # 獲取某個(gè)section名為Mysql-Database所對(duì)應(yīng)的鍵 print(options) items = cf.items("Mysql-Database") # 獲取section名為Mysql-Database所對(duì)應(yīng)的全部鍵值對(duì) print(items) host = cf.get("Mysql-Database", "host") # 獲取[Mysql-Database]中host對(duì)應(yīng)的值 print(host)
4.通過(guò)讀取配置文件
重新寫(xiě)一下之前的requests+正則表達(dá)式爬取貓眼電影的例子
把讀取配置文件readconfig.py和操作數(shù)據(jù)庫(kù)handleDB.py分別封裝到一個(gè)類中
readconfig.py如下
import configparser import os class ReadConfig: """定義一個(gè)讀取配置文件的類""" 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): """連接數(shù)據(jù)庫(kù)""" 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): """執(zhí)行操作數(shù)據(jù)的相關(guān)sql""" self.conn_mysql() self.cur.execute(sql, data) self.conn.commit() def search(self, sql): """執(zhí)行查詢sql""" self.conn_mysql() self.cur.execute(sql) return self.cur.fetchall() def close_mysql(self): """關(guān)閉數(shù)據(jù)庫(kù)連接""" self.cur.close() self.conn.close() if __name__ == '__main__': test = HandleMysql() sql = "select * from maoyan_movie" for i in test.search(sql): print(i)
最后的運(yùn)行文件,調(diào)用前面的方法
# coding: utf-8 # author: hmk import requests import re from common import handleDB class Crawler: """定義一個(gè)爬蟲(chóng)類""" 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>' # 匹配上映時(shí)間 r'.*?<i.*?"integer">(.*?)</i>' # 匹配分?jǐn)?shù)的整數(shù)位 r'.*?<i.*?"fraction">(.*?)</i>.*?</dd>', re.S) # 匹配分?jǐn)?shù)小數(shù)位 m = pattern.findall(html) for i in m: # 因?yàn)槠ヅ涞降乃薪Y(jié)果會(huì)以列表形式返回,每部電影信息以元組形式保存,所以可以迭代處理每組電影信息 ranking = i[0] # 提取一組電影信息中的排名 movie = i[1] # 提取一組電影信息中的名稱 release_time = i[2] # 提取一組電影信息中的上映時(shí)間 score = i[3] + i[4] # 提取一組電影信息中的分?jǐn)?shù),這里把分?jǐn)?shù)的整數(shù)部分和小數(shù)部分拼在一起 list_data.append([ranking, movie, release_time, score]) # 每提取一組電影信息就放到一個(gè)列表中,同時(shí)追加到一個(gè)大列表里,這樣最后得到的大列表就包含所有電影信息 def write_data(self, sql, data): self.db.conn_mysql() try: self.db.execute_sql(sql, data) print('導(dǎo)入成功') except: print('導(dǎo)入失敗') self.db.close_mysql() def run_main(self): start_url = 'http://maoyan.com/board/4' depth = 10 # 爬取深度(翻頁(yè)) 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參數(shù)是指正則匹配并處理后的列表數(shù)據(jù)(是一個(gè)大列表,包含所有電影信息,每個(gè)電影信息都存在各自的一個(gè)列表中; 對(duì)大列表進(jìn)行迭代,提取每組電影信息,這樣提取到的每組電影信息都是一個(gè)小列表,然后就可以把每組電影信息寫(xiě)入數(shù)據(jù)庫(kù)了)""" movie = i # 每組電影信息,這里可以看做是準(zhǔn)備插入數(shù)據(jù)庫(kù)的每組電影數(shù)據(jù) sql = "insert into maoyan_movie(ranking,movie,release_time,score) values(%s, %s, %s, %s)" # sql插入語(yǔ)句 self.write_data(sql, movie) if __name__ == '__main__': test = Crawler() test.run_main()
原文鏈接:https://blog.csdn.net/guoqianqian5812/article/details/68610760
相關(guān)推薦
- 2022-07-24 elment-ui的上傳組件圖片不回顯
- 2022-06-19 python?rsa和Crypto.PublicKey.RSA?模塊詳解_python
- 2023-02-18 Framework中實(shí)現(xiàn)OC和Swift的混編方案_IOS
- 2022-05-25 Jenkins 簡(jiǎn)單的從git上構(gòu)建一個(gè)maven項(xiàng)目
- 2022-09-21 Python數(shù)據(jù)庫(kù)反向生成Model最優(yōu)方案示例_python
- 2022-06-07 C語(yǔ)言非遞歸算法解決快速排序與歸并排序產(chǎn)生的棧溢出_C 語(yǔ)言
- 2022-04-18 python列表推導(dǎo)式實(shí)現(xiàn)找出列表中長(zhǎng)度大于5的名字_python
- 2023-03-02 Go語(yǔ)言讀取文本文件的三種方式總結(jié)_Golang
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細(xì)win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運(yùn)行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲(chǔ)小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運(yùn)算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認(rèn)證信息的處理
- Spring Security之認(rèn)證過(guò)濾器
- Spring Security概述快速入門(mén)
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯(cuò)誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實(shí)現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡(jiǎn)單動(dòng)態(tài)字符串(SD
- arthas操作spring被代理目標(biāo)對(duì)象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊(duì)列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠(yuǎn)程分支