1. 程式人生 > >Django 統計網站訪問次數、訪問 ip 、訪問端點及次數

Django 統計網站訪問次數、訪問 ip 、訪問端點及次數

個人部落格:http://www.iamnancy.top

有時候寫完部落格,想知道網站每天的訪問量,都有哪些人訪問,都是來自什麼地方的訪客,都訪問了哪些端點。

效果如下:

編寫 blog/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 檔案複製到專案的應用程式中 (我的網站是 ‘blog’)。專案結構如下圖所示:

編寫將 IP 轉換為現實地理位置的函式

blog/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

參考:Python獲取IP的地理位置:經緯度,國家,區域,城市

編寫 blog/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()

將上面的函式匯入到檢視中,在需要時直接呼叫

blog/view.py

...
from .visit_info import change_info


...
def post_detail(request, post_id):
    post = get_object_or_404(Post, id=post_id)
    post.yueduliang()
    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})

資料庫遷移

因為我們在 models.py 中建立了 3 個新類,所以需要執行以下命令,以使之作用於資料庫。

$ python manage.py makemigrations
$ python manage.py migrate

之後重啟下伺服器,這樣一個最簡單的頁面訪問量統計就完成了。

參考

django統計網站訪問次數,同時記錄訪問ip地址和次數
Python獲取IP的地理位置:經緯度,國家,區域,城市