作为父亲的失职
现在是凌晨三点半,我完成了今天的文章。之所以熬这么晚,主要是因为我这一对儿不听话的双胞胎。
今天孩子幼儿园发来了一张身心发展评价表,其中有一项社会文化的栏目,他俩都是一颗星(差),其中涉及的内容有:
会朗读和演唱简单的民间歌曲,喜欢听世界著名童话故事,能认识1-2个邻国的国旗。
他俩这项都是差让我有些愧疚,自问平时工作太忙,偶尔回家早些也想躺着玩会儿手机,陪孩子的时间不多。所谓子不教父之过,那么针对这个差我能做些什么?大概能认识1-2个邻国的国旗这项比较容易
数据获取
在网上翻了翻,找到一个统计国家、国旗、人口、面积的网站:
http://114.xixik.com/country-flag/
本来想着直接从第二张图的位置去获取,但发现国旗是缩略图,太小看不清。所以只好把这两张图拼接一起。通过国家名字进行关联了...
说干就干.....
网站分析
网站总体来说比较简单,统一的样式通过class的lindBox即可获取,下图微网站结构拼接图:
图片的下载和国家数据分别在第6个和第7个lindBox,对应index的5,6
图片解析img的src一级td的text,将名字对应保存即可
国家数据就更简单了直接for循环所有tr,使用正则格式化下就OK了
批量下载与存储
图片下载使用request.get(url)获取二进制数据,之后写入文件即可,至于目录,我们放在static/images下,至于为什么放这个目录,一会儿说....
国家数据由于不多,所以直接使用SQLite存储即可(其实存文本也行,但不方便后面使用)...
梳理OK,上代码:
# -*- coding: utf-8 -*-
# @Author : 王翔
# @JianShu : 清风Python
# @Date : 2019/6/11 2:19
# @Software : PyCharm
# @version :Python 3.6.8
# @File : CountryFlagCrawler.py.py
import requests
from bs4 import BeautifulSoup
import re
import os
from db_maker import DB_Maker as DB
class CountryFlagCrawler:
def __init__(self):
self.url = "http://114.xixik.com/country-flag/"
self.headers = {
'Host': "114.xixik.com",
'Connection': 'keep-alive',
'user-agent': ('Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 '
'(KHTML, like Gecko) Chrome/70.0.3538.67 Safari/537.36')
}
self.db = DB()
self.save_path = 'static/images'
def check_dir(self):
if not os.path.exists(self.save_path):
os.mkdir(self.save_path)
def get_response(self, url, params=None):
r = requests.get(url, headers=self.headers, params=params)
r.encoding = 'gb2312'
soup = BeautifulSoup(r.text, "lxml")
return soup
def down_load_flag(self):
soup = self.get_response(self.url)
tds = soup.findAll("div", {"class": "lindBox"})[5].findAll("td")
for td in tds:
try:
picture_url = td.find('img')['src']
country_name = '%s.gif' % re.sub('s', '', td.text)
print("Download %s" % country_name)
r = requests.get(picture_url)
with open(os.path.join(self.save_path, country_name), 'wb') as f:
f.write(r.content)
except:
pass
# contury_info
country_list = []
trs = soup.findAll("div", {"class": "lindBox"})[6].findAll("tr")
for tr in trs:
try:
info = list(map(lambda x: re.sub('s|,', '', x.text), tr.findAll('td')[1:]))
if len(info) == 4:
# 数据错误补充:
if info[0] == '俄罗斯':
country_list.append([info[0], info[1], int(info[2]), 17098246])
else:
country_list.append([info[0], info[1], int(info[2]), int(info[3])])
except:
pass
sql = "insert into country_flag (country,capital,population,area) values "
"(?,?,?,?)"
for line in sorted(country_list, key=lambda x: x[3], reverse=True):
self.db.insert(sql, line)
if __name__ == '__main__':
main = CountryFlagCrawler()
main.check_dir()
main.down_load_flag()
文中引用到了db_maker,是通过DBUtils封装的链接池,对这个感兴趣的可以看下我之前的文章:
决战高考,帮你秒变成语之王
看下效果吧:
数据获取.gif
数据获取完成,看到视频上的目录,大家应该知道下一步要做什么了。对通过Flask创建一个Web服务器。
Flask编写国旗学习网站
我们拿到了国旗与国家的数据,但孩子会喜欢学习吗?答案是NO,他俩只喜欢玩我和媳妇儿的手机。那么如果可以做成网站,在电脑上搭建web服务,一起和孩子通过手机访问学习,是不效果更好?走起....
我们要打到的效果大概是:访问网站,弹出国旗,测试后查看正确答案,支持上下翻页。先看看效果:
网站效果.gif
怎么做?其实很简单,引入bootstrap的css,然后网站设计图片、按钮、表格集中class,js简单设置下div的显隐就OK了。整体代码目录如下:
附上代码吧:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="">
<meta name="author" content="">
<link rel="icon" href="{{url_for('static',filename='favicon.ico')}}">
<title>父子学习认国旗</title>
<!-- Bootstrap core CSS -->
<link href="{{url_for('static',filename='css/bootstrap.min.css')}}" rel="stylesheet">
<!-- Custom styles for this template -->
<link href="{{url_for('static',filename='css/cover.css')}}" rel="stylesheet">
<script type="text/javascript">
function display(id) {
var traget = document.getElementById(id);
if (traget.style.display == "none") {
traget.style.display = "";
} else {
traget.style.display = "none";
}
}
</script>
</head>
<body>
<div class="site-wrapper">
<div class="site-wrapper-inner">
<div class="cover-container">
<div class="masthead clearfix">
<row>
<h1 class="cover-heading">父子学习认国旗</h1>
<div class="inner">
<p><img src="{{url_for('static',filename='images/%s.gif'|format(content[1]))}}" class="img-rounded"></p>
<p> <input type="submit" class="btn btn-success" value="查看详情..." onclick="display('lb')"></p>
</div>
<div class="inner cover">
<div id="lb" class="inner cover" style="display:none">
<div>
<table class="table table-bordered">
<tbody>
<tr>
<td>国家:</td>
<td>{{content[1]}}</td>
</tr>
<tr>
<td>首都:</td>
<td>{{content[2]}}</td>
</tr>
<tr>
<td>人口:</td>
<td>{{content[3]}}</td>
</tr>
<tr>
<td>面积</td>
<td>{{content[4]}}</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</row>
<div class="mastfoot">
{%if content[0] ==1%}
<a href="" disabled="disabled" class="btn btn-primary btn-sm">上一页</a>
{%else%}
<a href="{{url_for('index',country_id=content[0]-1)}}" class="btn btn-primary btn-sm">上一页</a>
{%endif%}
<a href="{{url_for('index',country_id=content[0]+1)}}" class="btn btn-primary btn-sm">下一页</a>
<div class="inner">
<p>by <a href="https://www.jianshu.com/u/d23fd5012bed">清风Python</a></p>
</div>
</div>
</div>
</div>
</div>
</div>
</body>
</html>
# -*- coding: utf-8 -*-
# @Author : 王翔
# @JianShu : 清风Python
# @Date : 2019/6/11 3:24
# @Software : PyCharm
# @version :Python 3.6.8
# @File : CountryFlagFlask.py
from flask import Flask, render_template, g,
from db_maker import DB_Maker as DB
app = Flask(__name__)
@app.before_request
def connect():
g.db = DB()
@app.route('/')
@app.route('/<int:country_id>')
def index(country_id=1):
result = g.db.fetch_one("select * from country_flag where id=%s" % country_id)
print(result)
return render_template("index.html", content=result)
if __name__ == '__main__':
app.run(host='0.0.0.0')
手机访问
手机访问效果.gif
明天早点回家,跟孩子一起收集上学习认国旗吧,哈哈.....
好了,今天的内容就到这里,如果觉得有帮助,记得点赞支持。欢迎大家关注我的公众号【清风Python】,
整套代码和数据,我会打包放在百度云盘,公众号回复关键字 国旗 即可获得下载地址。
来源:清风Python