新冠疫情爬虫实现
简单做的疫情爬取Python代码,只爬了国外的数据,登录名是osadmin和user两个,功能不一样,密码需要直接新建account.txt文件,在里面创建用户名和密码。
源码:
# -*- coding:utf-8 -*-
from lxml import etree
import sys
import os
import getpass
import sqlite3
import os
import requests
from PIL import Image
from prettytable import PrettyTable
import DaPy as dp
import pandas as pd
import matplotlib.pyplot as plt
codeLib = '''qwertyuiopasdfghjkl;'zxcvbnm,./1234567890-!@#$%^&*(*()_QWERTYUIOAS<>DFGHJKL:ZXCVBNM........'''
count = len(codeLib)
# os.system('clear')
host = "https://www.bitpush.news/covid19/"
conn = sqlite3.connect('qqyiqing.db')
cursor = conn.cursor()
sql = '''create table qqyiqing_tb(
area varchar(20),
new int,
death int
)'''
conn.commit() # 提交
conn.close()
# 显示团队logo
def pic2str():
text = ""
# 取出每个像素点
for h in range(0, imgfile.size[1]):
for w in range(0, imgfile.size[0]):
g, r, b = imgfile.getpixel((w, h))
# 获得对应坐标的像素值
# 转换为灰度值
gray = int(r*0.299+g*0.587+b*0.114)
# 0-255
# 通过该值替换字符库
text = text+codeLib[int(((count-1)*gray)/256)]
text = text+"\n"
return text
if __name__ == '__main__':
# 打开图片
fp = open("1.jpg", 'rb')
imgfile = Image.open(fp)
imgfile = imgfile.resize(
(int(imgfile.size[0]*0.7), int(imgfile.size[1]*0.3)))
# 普通用户
def showMenu_user():
logoStr=pic2str()
linStr = '='*50
version = '''version 1.0.0'''
menuStr = '''
[1]开始爬取数据并储存
[2]退出系统
'''
print(logoStr)
print(linStr)
print(version)
while True:
print(menuStr)
menuSelect = input('请输入菜单项>>')
if menuSelect == '1':
print("数据查询中,请稍后")
getData(host, encode='utf-8')
elif menuSelect == '2':
print("欢迎下次使用!!!")
break
else:
print('请输入正确的菜单序号!!!!')
# 管理员用户
def showMenu_admin():
logoStr=pic2str()
linStr = '='*50
version = '''version 1.0.0'''
menuStr = '''
[1]修改数据
[2]删除数据
[3]查询数据
[4]可视化展示
[5]退出系统
'''
print(logoStr)
print(linStr)
print(version)
while True:
print(menuStr)
menuSelect = input('请输入菜单项>>')
if menuSelect == '1':
print("请按要求输入信息后【回车】")
alter()
elif menuSelect == '2':
print("请按要求输入信息后【回车】")
delete()
elif menuSelect == '3':
print("请按要求输入信息后【回车】")
queryBy()
elif menuSelect == '4':
show()
elif menuSelect == '5':
print("欢迎下次使用!!!")
break
else:
print('请输入正确的菜单序号!!!!')
# 爬取的网站
# 爬取数据并存储
def getData(host, encode='utf-8'):
response = requests.get(host)
# 如果页面乱码,则需要设置编码
response.encoding = encode
if response.status_code == 200:
print("爬取数据成功")
index = response.text
index_root = etree.HTML(index)
# 可以开始解析数据
index_area = index_root.xpath(
"//div[@id='main']/div[1]/div/div/div/div/div[1]/table/tbody/tr/td[1]/span/text()")
index_diagnosed = index_root.xpath(
"//div[@id='main']/div[1]/div/div/div/div/div[1]/table/tbody/tr/td[2]/text()")
index_death = index_root.xpath("//div[@id='main']/div[1]/div/div/div/div/div[1]/table/tbody/tr/td[3]/text()")
conn = sqlite3.connect('qqyiqing.db')
cursor = conn.cursor()
cursor.execute('''create table qqyiqing_tb(
area varchar(50),
diagnosed varchar(50),
death varchar(50))
'''
)
a = 0
for area in index_area:
cursor.execute(
'''insert into qqyiqing_tb values('{}','{}','{}') '''.format(area, index_diagnosed[a], index_death[a]))
a = a + 1
conn.commit() # 提交
conn.close()
# 查询
def queryBy():
b = input('''
请选择要查询的项目:
[1]查询单个国家
[2]查询全部国家
''')
if b == '1':
area = input("请输入要查询的国家名称>>")
querysql = '''select * from qqyiqing_tb where area='{}' '''.format(area)
# 连接
conn = sqlite3.connect('qqyiqing.db')
# 打开
cursor = conn.cursor()
result = cursor.execute(querysql)
table = PrettyTable()
table.field_names = ['Name', 'Age', 'Country']
for row in result:
table.add_row(row)
conn.close()
print(table)
print('查询结果如上,没有结果表示没有相关信息')
input("按【回车键】返回菜单")
os.system('cls')
elif b == '2':
querysql = '''select * from qqyiqing_tb'''
conn = sqlite3.connect('qqyiqing.db')
cursor = conn.cursor()
result = cursor.execute(querysql)
table = PrettyTable()
table.field_names = ['Name', 'Age', 'Country']
for row in result:
table.add_row(row)
conn.close()
print(table)
print('查询结果如上,没有结果表示没有相关信息')
input("按【回车键】返回菜单")
os.system('cls')
# 删除
def delete():
area = input("请输入需要删除信息的国家>>")
deletesql = '''delete from qqyiqing_tb where area='{}' '''.format(area)
# 连接
conn = sqlite3.connect('qqyiqing.db')
# 打开
cursor = conn.cursor()
result = cursor.execute(deletesql)
conn.commit()
conn.close()
print('删除信息成功!')
input("按【回车键】返回菜单")
os.system('cls')
# 修改
def alter():
menustr = '''
请输入要修改的信息:
[1]修改地区
[2]修改现有确诊
[3]修改死亡人数
'''
print(menustr)
sort = eval(input("请输入要指行的命令>>"))
if sort == 1:
an = "area"
elif sort == 2:
an = "diagnosed"
elif sort == 3:
an = "death"
last = input("请输入修改前的值:")
now = input("请输入修改后的值:")
altersql = '''update qqyiqing_tb set {} = '{}' where {} = '{}' '''.format(an, now, an, last)
conn = sqlite3.connect('qqyiqing.db')
cursor = conn.cursor()
cursor.execute(altersql)
conn.commit()
conn.close()
print('修改信息成功!')
input("按【回车键】返回菜单")
os.system('cls')
#展示数据
def show():
sheet = dp.read("qqyiqing.db")
sheet.save("shuju.xls")
df = pd.read_excel("shuju.xls")
print(df)
print(df["diagnosed"])
plt.plot(df["area"],df["diagnosed"],label='diagnosed',linewidth=3,color='r',marker='o',
markerfacecolor='blue',markersize=3)
plt.plot(df["area"],df["death"],label='death',linewidth=3,color='y',marker='o',
markerfacecolor='yellow',markersize=3)
plt.xlabel("area")
plt.ylabel('count')
plt.title("data")
plt.legend()
plt.grid()
plt.show()
i = 0
while i < 3:
name = input("请输入用户名:")
lock_file = open('account_lock.txt', 'r+')
lock_list = lock_file.readlines()
for lock_line in lock_list:
lock_line = lock_line.strip('\n')
if name == lock_line:
sys.exit('用户 %s 已经被锁定,退出' % (name))
user_file = open('account.txt', 'r')
user_list = user_file.readlines()
for user_line in user_list:
(user, password) = user_line.strip('\n').split()
if name == user:
j = 0
while j < 3:
# passwd = getpass.getpass('请输入密码:')
passwd = input('请输入密码:')
if passwd == password:
if name == "osadmin":
print("用户%s登录成功" % name)
showMenu_admin()
sys.exit(0)
if name == "user":
print("用户%s登录成功" % name)
showMenu_user()
sys.exit(0)
else:
if j != 2:
print("用户 %s 密码错误,请重新输入,还有 %d 次机会" % (name, 3 - j))
j += 1
else:
lock_file.write(name + '\n')
sys.exit('用户 %s 达到最大登录次数,将被锁定并退出' % name)
else:
pass
else:
if i != 2:
print('用户名%s 不存在,请重新输入,还有 %d 次机会' % (name, 3 - i))
i += 1
else:
sys.exit("用户 %s 不存在,退出" % name)
需要创建两个文本文件储存用户名密码和登录次数过多锁定的用户。
还需要有一个图片当作logo使用。