想知道网站每天的访问量,都有哪些人访问,都是来自什么地方的访客,都访问了哪些端点。
编写 models.py
# 访问网站的 ip 地址、端点和次数
class UserIP(models.Model):
ip = models.CharField(verbose_name='IP 地址', max_length=30)
ip_addr = models.CharField(verbose_name='IP 地理位置', max_length=30)
end_point = models.CharField(verbose_name='访问端点', default='/', max_length=30)
count = models.IntegerField(verbose_name='访问次数', default=0)
class Meta:
verbose_name = '访问用户信息'
verbose_name_plural = verbose_name
def __str__(self):
return self.ip
# 网站总访问次数
class VisitNumber(models.Model):
count = models.IntegerField(verbose_name='网站访问总次数', default=0) # 网站访问总次数
class Meta:
verbose_name = '网站访问总次数'
verbose_name_plural = verbose_name
def __str__(self):
return str(self.count)
# 单日访问量统计
class DayNumber(models.Model):
day = models.DateField(verbose_name='日期', default=timezone.now)
count = models.IntegerField(verbose_name='网站访问次数', default=0) # 网站访问总次数
class Meta:
verbose_name = '网站日访问量统计'
verbose_name_plural = verbose_name
def __str__(self):
return str(self.day)
使用 geoip2 实现 IP 转换成现实地理位置
安装 geoip2 库
pip install geoip2
下载 Maxmind 网站的 IP 信息库
地址:http://dev.maxmind.com/geoip/geoip2/geolite2
下载完之后,解压,将解压包中的 mmdb 文件复制到项目的应用程序中
下载个GeoLite2 City使用。
然后我们的python代码如下:
#!/usr/bin/python
#-*-coding:utf-8-*-
import geoip2.database
reader = geoip2.database.Reader('./GeoLite2-City.mmdb')
ip = raw_input("输入你要查询的IP:\n")
response = reader.city(ip)
# 有多种语言,我们这里主要输出英文和中文
print("你查询的IP的地理位置是:")
print("地区:{}({})".format(response.continent.names["es"],
response.continent.names["zh-CN"]))
print("国家:{}({}) ,简称:{}".format(response.country.name,
response.country.names["zh-CN"],
response.country.iso_code))
print("洲/省:{}({})".format(response.subdivisions.most_specific.name,
response.subdivisions.most_specific.names["zh-CN"]))
print("城市:{}({})".format(response.city.name,
response.city.names["zh-CN"]))
print("经度:{},纬度{}".format(response.location.longitude,
response.location.latitude))
print("时区:{}".format(response.location.time_zone))
print("邮编:{}".format(response.postal.code))
试一试
(venv) allenwoo@~/renren/code$ python test.py
输入你要查询的IP:
112.74.207.96
你查询的IP的地理位置是:
地区:Asia(亚洲)
国家:China(中国) ,简称:CN
洲/省:Zhejiang(浙江省)
城市:Hangzhou(杭州)
经度:120.1614,纬度30.2936
时区:Asia/Shanghai
邮编:None
再来一个:
(venv) allenwoo@~/renren/code$ python test.py
输入你要查询的IP:
223.192.2.165
你查询的IP的地理位置是:
地区:Asia(亚洲)
国家:China(中国) ,简称:CN
洲/省:Beijing(北京市)
城市:Beijing(北京)
经度:116.3883,纬度39.9289
时区:Asia/Shanghai
邮编:None
2.至于在线库的使用是需要一个license_key
只有前面两步不太一样
连接: client = geoip2.webservice.Client(42, <license_key>)
查询 IP: response = client.insights(<IP>)
编写将 IP 转换为现实地理位置的函数
ip_convert_addr.py
import geoip2.database
def ip_to_addr(ip):
"""
IP 转换成现实中的地理位置
country = 国家
province = 省
city = 城市
"""
reader = geoip2.database.Reader('blog/GeoLite2-City.mmdb')
response = reader.city(ip)
#print(response)
# 因为有些IP的省份和城市未知,所以设置默认为空
province = ''
city = ''
try:
# 国家、省份、城市
country = response.country.names["zh-CN"]
province = response.subdivisions.most_specific.names["zh-CN"]
city = response.city.names["zh-CN"]
except:
pass
if country != '中国':
return country
if province and city:
if province == city or city in province:
return province
return '%s%s' %(province, city)
elif province and not city:
return province
else:
return country
编写 visit_info.py
实现更新网站访问量和访问 ip 等信息
from django.utils import timezone
from .models import UserIP, VisitNumber, DayNumber
from .ip_convert_addr import ip_to_addr
# 自定义的函数,不是视图
def change_info(request, end_point):
"""
# 修改网站访问量和访问 ip 等信息
# 每一次访问,网站总访问次数加一
"""
count_nums = VisitNumber.objects.filter(id=1)
if count_nums:
count_nums = count_nums[0]
count_nums.count += 1
else:
count_nums = VisitNumber()
count_nums.count = 1
count_nums.save()
# 记录访问 ip 和每个 ip 的次数
if 'HTTP_X_FORWARDED_FOR' in request.META: # 获取 ip
client_ip = request.META['HTTP_X_FORWARDED_FOR']
client_ip = client_ip.split(",")[0] # 所以这里是真实的 ip
else:
client_ip = request.META['REMOTE_ADDR'] # 这里获得代理 ip
# print(client_ip)
ip_exist = UserIP.objects.filter(ip=str(client_ip), end_point=end_point)
if ip_exist: # 判断是否存在该 ip
uobj = ip_exist[0]
uobj.count += 1
else:
uobj = UserIP()
uobj.ip = client_ip
uobj.end_point = end_point
try:
uobj.ip_addr = ip_to_addr(client_ip)
except:
uobj.ip_addr = 'unknown'
uobj.count = 1
uobj.save()
# 增加今日访问次数
date = timezone.now().date()
today = DayNumber.objects.filter(day=date)
if today:
temp = today[0]
temp.count += 1
else:
temp = DayNumber()
temp.dayTime = date
temp.count = 1
temp.save()
将上面的函数导入到视图中,在需要时直接调用
from .visit_info import change_info
...
def post_detail(request, post_id):
post = get_object_or_404(Post, id=post_id)
change_info(request, '/')
# 记得在顶部引入 markdown 模块
post.body = markdown.markdown(post.body, extensions=['extra', 'codehilite', 'toc',
'tables', 'sane_lists'])
return render(request, 'post_detail.html', context={'post': post})