python读取配置⽂件简单封装
之前有做过把爬⾍数据写到数据库中的练习,这次想把数据库信息抽离到⼀个ini配置⽂件中,这样做的好处在于可以在配置⽂件中添加多个数据
库,⽅便切换(另外配置⽂件也可以添加诸如邮箱、url等信息)
python使⽤⾃带的configparser模块⽤来读取配置⽂件,配置⽂件的形式类似windows中的ini⽂件
在使⽤前需要先安装该模块,使⽤pip安装即可
(1)新建⼀个config.ini⽂件,如下
(2)新建⼀个readconfig.py⽂件,读取配置⽂件的信息
许君豪import configparser
cf = configparser.ConfigParser()
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()
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()
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()
ad(configpath)
def get_db(self, param):
value = ("Mysql-Database", param)
return value
if __name__ == '__main__':
广西旅游
test = ReadConfig()
t = _db("host")
print(t)
handleDB.py如下
# coding: utf-8
# author: hmk
adconfig import ReadConfig
import pymysql.cursors
class HandleMysql:
def __init__(self):
self.data = ReadConfig()
def conn_mysql(self):
"""连接数据库"""
host = _db("host")
user = _db("user")
password = _db("password")
db = _db("db")
charset = _db("charset")
< = t(host=host, user=user, password=password, db=db, charset=charset)
self.cur = ursor()
def execute_sql(self, sql, data):
"""执⾏操作数据的相关sql"""
<_mysql()
ute(sql, data)
def search(self, sql):
"""执⾏查询sql"""
<_mysql()
ute(sql)
return self.cur.fetchall()
def close_mysql(self):
"""关闭数据库连接"""
self.cur.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 = (url=url, headers=header)
if response.status_code == 200:
else:
return None
@staticmethod
def get_data(html, list_data):
pattern = repile(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):
_mysql()
try:
ute_sql(sql, data)
print('导⼊成功')
except:
print('导⼊失败')
self.db.close_mysql()
def run_main(self):
start_url = 'maoyan/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",
"Referer": "maoyan/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 = _html(url, header)
list_data = []
<_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()