class="markdown_views prism-github-gist">
##python小白,家庭作业一篇,本篇仅适合新手练习,大牛勿喷,欢迎交流~
import requests # 调用申请模块
import json # 调用json数据模块
import sqlite3 # 引入数据库
from func_items import Esport_Sql, Esport_User # 从功能模块调用电竞圈数据库函数
class E_Sport(object):
'''一个电竞圈的数据模型'''
def __init__(self):
'''定义数据模型的基本属性'''
self.url = 'http://api2.dianjingquan.cn:3004/match/query/list?page=1&page_count=40&key=&status=all&game_id=0'#初始网址
self.headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36'
}#请求头
self.create_table()#调用静态函数,创建数据库表
self.document = ''#定义获取到的网页源码转换后的json格式数据,初始值为空
self.response = '' #定义返回的网页源代码数据,初始值为空
self.error_count = 0 #定义错误次数初始值为0
@staticmethod # 静态函数装饰器
def create_table():
'''创建数据库表的静态函数'''
database = sqlite3.connect('E_Sport.db') # 连接数据库
cursor = database.cursor() # 启动游标
sql_01 = "CREATE TABLE IF NOT EXISTS E_Sport_Match(m_id INTEGER PRIMARY KEY,m_title VARCHAR (20),m_name VARCHAR (10),m_date VARCHAR (30),m_reward VARCHAR (10),game_rules TEXT,details TEXT,m_max_count VARCHAR (10),m_count VARCHAR (10),m_img CHAR,m_url CHAR )" # 创建数据表,存放赛事信息
cursor.execute(sql_01)#执行sql语句
sql_02 = "CREATE TABLE IF NOT EXISTS E_Sport_User(user_id INTEGER PRIMARY KEY ,user_name VARCHAR (10),add_time VARCHAR (20),mobile VARCHAR (20))" # 创建数据表,存放玩家信息
cursor.execute(sql_02) # 执行sql语句
cursor.close() # 关闭游标
database.close() # 关闭数据库
def get_html(self, is_list=True):
'''采集函数 发请求 拿数据'''
try: # 调用异常捕获,以防程序报错
response = requests.get(self.url, headers=self.headers) # 发请求 拿回数据
self.response = response.text #text文本
print('-' * 30)
except Exception as error: # 异常捕获,如果程序出错,会走这里的代码
self.error_count += 1 # 每次出错,错误次数+1
if self.error_count > 3: # 此处加以判断,如果出错次大于3
print('重连次数过多,将跳过此条..') # 程序提前结束
return
self.get_html(is_list=is_list) # 若出错次数在3之内,继续调用采集函数,直到成功返回数据or提前结束
else:
self.error_count = 0 # 三次之内成功,错误次数归 0
if is_list: # 判断参数布尔值是否为真
self.parse_html() # 为True才会调用起始页解析函数
def parse_html(self):
'''解析函数:解析起始页的数据'''
self.document = json.loads(self.response) # 将返回的数据转换成json格式
pages = self.document.get('pages') # 获取全部赛事的总页数
total_matches = self.document.get('total') # 获取全部赛事的数量
matches = self.document.get('matchs') # 获取当前页赛事的信息,得到一个列表,包含四十个字典数据
print('正在采集起始页数据.')
print('
')
for match in matches: # 迭代这个列表,准备解析数据
m_id = match.get('id') # 获取赛事id,根据这个id,可以在之后的详情页请求中拿回更多的数据
m_title = match.get('name') # 获取赛事标题
m_name = match.get('game_name') # 获取游戏名称
m_img = match.get('banner_url') # 获取赛事宣传图片地址
m_date = match.get('create_time') # 获取赛事创立时间
m_max_count = match.get('max_enroll_count') # 获取赛事报名人数限制
m_count = match.get('enroll_count') # 获取已报名人数数量
m_reward = match.get('total_reward') # 获取赛事奖金金额
self.url = f'http://api2.dianjingquan.cn:3004/match/base?match_id={m_id}&uid=0&access_token=' #通过赛事id拼接一个完整的赛事主办方详情页网址
self.get_html(is_list=False) # 此处调用采集函数对赛事主办方详情页进行采集时,传递的布尔值函数为False,故采集函数不会调用解析起始页的函数
print(f'正在采集"{m_title}"主办方信息..')
self.parse_host(m_id, m_title, m_name, m_date, m_max_count, m_count, m_reward,
m_img) # 调用解析函数对赛事主办方详情页进行解析,并且将已获得的部分数据传给解析函数,以便保存
self.url = f'http://api2.dianjingquan.cn:3004/match/user/list?match_id={m_id}&uid=0&access_token=' # 通过赛事id拼接一个完整的参赛人员详情页地址
self.get_html(is_list=False) # 此处调用采集函数对参赛人员详情页进行采集时,传递的布尔值函数为False,故采集函数不会调用解析起始页的函数
print('
')
print(f'正在采集"{m_title}"参赛人员信息..')
self.parse_user() # 调用解析参赛人员的数据
for x in range(2, pages): # 已知全部赛事的总页数为pages 开始下一页的采集
print('☀'*30)
print(f'正在采集第{x}页..')
print('
')
self.url = f'http://api2.dianjingquan.cn:3004/match/query/list?page={x}&page_count=40&key=&status=all&game_id=0'#拼接下一页的地址
self.get_html()#调用采集函数,对下一页网址发起请求
def parse_user(self):
'''解析函数:解析参赛人员详情页的数据'''
self.document = json.loads(self.response) # 将返回的数据转化成json格式,为字典数据
user_lists = self.document.get('enroll_list') # 提取报名参赛人员详细信息,得到一个列表嵌套字典的数据
for user_list in user_lists: # 迭代这个列表
user_id = user_list.get('id') # 提取玩家id
user_name = user_list.get('id_name') # 提取参赛玩家昵称
mobile = user_list.get('mobile') # 提取玩家手机号
add_time = user_list.get('add_time') # 获取玩家提交时间
print('正在写入数据库..')
print('
')
user = Esport_User(user_id, user_name, add_time, mobile) # 创建一个Esport_User的模型对象,并将参数传入
user.save() # 调用Esport_User的保存数据函数
def parse_host(self, m_id, m_title, m_name, m_date, m_max_count, m_count, m_reward, m_img):
'''解析函数:解析赛事主办方详情页的数据'''
self.document = json.loads(self.response) # 将返回的数据转换为json格式
try: # 根据报错得知,有的数据里没有赛事规则,故调用异常捕获
game_rules = self.document.get('custom_property_list')[0].get('content') # 获取赛事规则
except Exception as e:
game_rules = '规则缺失'
infos = self.document.get('contact_list') # 获取主办方联系方式,得到一个列表嵌套三个字典的数据
details = '' # 主办方联系方式有好几种,先定义一个空字符串,后面往里填
for info in infos: # 迭代这个列表
type = info.get('type') # 获取主办方联系方式的具体信息
value = info.get('value')
details += type + ':' + value + '|' # 将每次循环得到的结果用特定符号连接,然后填进字符串里
esport = Esport_Sql(m_id, m_title, m_name, m_date, m_reward, game_rules, details, m_max_count, m_count, m_img,
self.url) ##建立一个ESport_Sql的对象
print('
')
print('正在写入数据库..')
esport.save() # 调用ESport_Sql的赛事保存数据函数
def run(self):
'''程序启动函数'''
print('❀'*50)
print('✲'*30)
print('*'*20)
print('*'*10)
print('启动程序')
self.get_html()
if __name__ == '__main__':#在当前类调用
sport = E_Sport()#创建一个电竞圈模型的实例
sport.run()#启动函数
数据库代码封装,如下
import sqlite3#引入数据库
class Esport_Sql():
'''电竞圈爬取数据保存数据模型'''
def __init__(self,m_id,m_title,m_name,m_date,m_reward,game_rules,details,m_max_count,m_count,m_img,m_url):
self.m_title = m_title
self.m_id = m_id
self.m_name =m_name
self.m_date = m_date
self.m_reward = m_reward
self.game_rules = game_rules
self.details = details
self.m_max_count = m_max_count
self.m_count = m_count
self.m_img = m_img
self.m_url = m_url
def save(self):
'''赛事保存数据函数'''
database = sqlite3.connect('E_Sport.db')
cursor = database.cursor()
insert_sql = f"""INSERT INTO E_Sport_Match(m_id,m_title,m_name,m_date,m_reward,game_rules,details,m_max_count,m_count,m_img,m_url) VALUES ({self.m_id},'{self.m_title}','{self.m_name}','{self.m_date}','{self.m_reward}','{self.game_rules}',"{self.details}",'{self.m_max_count}','{self.m_count}','{self.m_img}','{self.m_url}')"""
try:#因数据有可能会重复,故调用异常捕获
cursor.execute(insert_sql)
database.commit()
except Exception as error:
print('该条数据已经存在!')
cursor.close()#关闭游标
database.close()#关闭数据库
class Esport_User():
'''有关参赛玩家的数据模型'''
def __init__(self,user_id,user_name,add_time,mobile):
'''定义参赛玩家数据模型的初始属性'''
self.user_id = user_id
self.user_name = user_name
self.add_time = add_time
self.mobile = mobile
def save(self):
database = sqlite3.connect('E_Sport.db')
cursor = database.cursor()
insert_sql = f"INSERT INTO E_Sport_User(user_id,user_name,add_time,mobile) VALUES ({self.user_id},"
f"'{self.user_name}','{self.add_time}','{self.mobile}') "
try: # 因数据有可能会重复,故调用异常捕获
cursor.execute(insert_sql)
database.commit()
except Exception as error:
print('该条数据已经存在!')
cursor.close()#关闭游标
database.close()#关闭数据库
程序爬取界面
数据库界面
现在的任务就是找bug了(手动狗头)~~
#end()