文章主要参考:https://www.cnblogs.com/hanmk/p/9843136.html
首先感谢原创作者为我提供了学习参考,本文记录了在学习原文中遇到的问题,以此记录自己的学习情况。
Python配置文件的使用与设计、类封装
1、configparser模块
Python使用自带的configparser模块来读取配置文件,配置文件的形式类似Windows中的ini文件,首先需安装该模块
命令:pip inatall configparser
2、configparser读取文件的基本方法
2.1配置文件config.ini
[Mysql-Database]
host=localhost
user=root
password=123456
db=test
charset=utf8
[Email]
host = https://reg.163.com/logins.jsp
address = 18607146150@163.com
password = 123456
2.2 readconfig.py文件,读取配置文件的信息
import configparser
cf = configparser.ConfigParser()
cf.read("D:\PycharmWorkspace\done\config\config.ini") # 读取配置文件,如果写文件的绝对路径,就可以不用os模块
# 获取文件中所有的section(一个配置文件中可以有多个配置,如数据库相关的配置,邮箱相关的配置,每个section由[]包裹,即[section]),并以列表的形式返回
secs = cf.sections()
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)
运行结果
3、引入os模块,使用相对目录读取配置文件
工程目录如下:
readconfig.py
import configparser
import os
cf = configparser.ConfigParser()
cf.read(os.path.abspath("config.ini")) # 使用os模块,读取当前目录下的文件
# 获取文件中所有的section(一个配置文件中可以有多个配置,如数据库相关的配置,邮箱相关的配置,每个section由[]包裹,即[section]),并以列表的形式返回
secs = cf.sections()
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
import configparser
import os
class ReadConfig:
"""定义一个读取配置文件的类"""
def __init__(self, filepath=None):
if filepath:
configpath = filepath
else:
cf = configparser.ConfigParser()
configpath = cf.read(os.path.abspath("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)
handled.py
# coding: utf-8
from config.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)
tiaoyong.py
# coding: utf-8
import requests
import re
from config 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()
# noinspection PyBroadException
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/71.0.3578.80 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()
运行结果:
注意建表时字段属性都是varchar