# -*- coding: utf-8 -*- """ ページの流れをもとにしたレコメンドロジック """ import datetime as dt import re import sys sys.path.append("/var/local/mode2") from .base import ModelBase from lib.WebRecommend.utils.dataAccess import dataAccess class SiteFlow(ModelBase): def __init__(self, domain=False): self.recommend_category = 'site_flow' self.da = dataAccess(domain) self.domain = domain def calcTrend(self, **kwargs): get_data = self.da.getInternalTop() datadict = {} datalist = [] data = [] if 'results' in get_data: return data else: for k, v in get_data.items(): for i in v: if i['nb_visits'] > 0: if i['label'] == 'index': url = '' else: url = re.sub(r'/index$', '/', i['label']) if url in datadict.keys(): datadict[url] += int(i['nb_hits']) else: datadict[url] = int(i['nb_hits']) for k, v in datadict.items(): datalist.append([k, v]) datalist.sort(key=lambda x: x[1], reverse=True) rank = 1 max = len(datalist) for i in range(0, 10): if rank <= max: data.append({'RANK': rank, 'NAME': "/" + datalist[i][0], 'VALUE': datalist[i][1]}) else: data.append({'RANK': rank, 'NAME': "", 'VALUE': "", 'LINK': ''}) rank += 1 return data def calcLinkDiversity(self, target=""): # shortName websiteにおけるリンク元の偏りを計算 data = [] # get index page by default get_data = self.da.getFlow(access_path=target) ratio = 0.0 num = 0 total_refs = 0 if not 'results' in get_data: LOCAL_DOMAIN = get_data['LOCAL_DOMAIN'] search_engine = ['http://search.yahoo.co.jp/', 'https://search.yahoo.co.jp/', 'https://www.bing.com/'] if 'referrers' in get_data: try: for i in get_data['referrers']: if i['shortName'] == "website": for j in i['details']: if j['label'] not in search_engine: if j['label'] != "Others": url = re.sub( r'/index$', '/', j['label']).replace(LOCAL_DOMAIN, "") data.append( dict(page=url, value=int(j['referrals']))) # Othersも含めたreferrals数 total_refs += int(j['referrals']) data.sort(key=lambda x: x['value'], reverse=True) if len(data) == 1: ratio = float(data[0]['value'])/float(total_refs) num = 1 elif len(data) == 2: ratio = float(data[0]['value']+data[1] ['value']) / float(total_refs) num = 2 elif len(data) > 2: # リンク元が3以上の時はTOP3が占める割合を計算 ratio = float( data[0]['value']+data[1]['value']+data[2]['value']) / float(total_refs) num = 3 else: ratio = 0.0 num = 0 except Exception as e: pass res = dict(num=num, ratio=ratio, total_refs=total_refs) return res def calcFlow(self, target=""): data = [] # get index page by default get_data = self.da.getFlow(access_path=target) if 'results' in get_data: return data else: LOCAL_DOMAIN = get_data['LOCAL_DOMAIN'] if 'followingPages' in get_data: for i in get_data['followingPages']: url = re.sub(r'/index$', '/', i['label']).replace(LOCAL_DOMAIN, "") data.append(dict(page=url, value=int(i['referrals']))) data.sort(key=lambda x: x['value'], reverse=True) return data def getNextFlows(self, access_path, next_num=3): try: if access_path: next_access = self.calcFlow(access_path.lstrip('/')) if len(next_access) > 0: next_access_after_list = [ f for f in next_access if not f['page'] == 'Others'] # Othersを除く if len(next_access_after_list) > 0: return next_access_after_list[:next_num] return None except: return None def getRecommend(self): res = [] top10 = self.calcTrend() if not len(top10) > 1: return res # 主なページ遷移を計算する try: d = dt.datetime.now() week = d.weekday() if week == 0: main_flows = [] for access in top10[:3]: # TOP3 tmp_first_access = access print(access) next_access_list = self.getNextFlows(access['NAME']) print(next_access_list) tmp_new_next_access_list = [] if next_access_list: for na in next_access_list[:3]: if na: tmp_access_after_next = self.getNextFlows( na['page'], next_num=1) if tmp_access_after_next: tmp_access_after_next = tmp_access_after_next[0] tmp_next_access = na # 1つを取得 tmp_next_access['following'] = tmp_access_after_next tmp_new_next_access_list.append( tmp_next_access) tmp_first_access['FOLLOWING'] = tmp_new_next_access_list main_flows.append(tmp_first_access) # TOP1位のアクセスフロー if len(main_flows) > 0: if 'FOLLOWING' in main_flows[0]: if main_flows[0]['FOLLOWING'] > 0: if 'following' in main_flows[0]['FOLLOWING'][0]: text = u"1位のアクセスページからの主なページ遷移は(%s, %sアクセス)->(%s, %sアクセス)->(%s, %sアクセス)となっているようです。意図したページ遷移となっていなければ、目的ページへのリンクを目立つように配置してみてはいかがでしょうか。" % ( main_flows[0]['NAME'], main_flows[0]['VALUE'], main_flows[0]['FOLLOWING'][0]['page'], main_flows[0]['FOLLOWING'][0]['value'], main_flows[0]['FOLLOWING'][0]['following']['page'], main_flows[0]['FOLLOWING'][0]['following']['value']) res.append( dict(date=str(dt.date.today()), text=text)) except Exception as e: pass try: # アクセスTOP10の1位と2位の差を比較し、2位が1位より3割以上アクセスが少ない場合 if float(top10[0]['VALUE'])*0.7 > float(top10[1]['VALUE']): if top10[0]['NAME'] == "/": page = u"TOPページ" else: page = top10[0]['NAME'] text = u"ページ別アクセス数の1位と2位のアクセス数の差が3割以上開いているようです。訪問者は"+page+u"のみ閲覧して終了しているかもしれません。" + \ page+u"の次に閲覧してもらいたいページへのリンクを設置したり、目立たせたりしてページ遷移を改良すると、訪問者の滞在時間を増やせる可能性があります。" res.append(dict(date=str(dt.date.today()), text=text)) except: pass try: # アクセス1位のページがTOPかどうか if not top10[0]['NAME'] == "/": text = u"アクセスページの1位がTOPページ(/)ではないようです。検索トレンドや関連検索ワードで人気のワードを把握し、トップページにそのワードを増やすことでアクセス数の増加が期待できます。またトップページに" + \ top10[0]['NAME'] + u"のリンクを設置すると、" + \ top10[0]['NAME'] + u"へのアクセス数の維持が期待できます。" res.append(dict(date=str(dt.date.today()), text=text)) except: pass try: # TOPの次に遷移するページはなにか following = self.calcFlow() if len(following) > 0: total = 0 # Others以外で見られたページの合計値 for i in following: if i['page'] != "Others": total += int(i['value']) # よく見られるページTOPの割合を計算 follow_page_ratio = float(following[0]['value'])/float(total) if following[0]['page'] == "Others": text = u"トップページ(/)の次に遷移しているページは特定のページではなく、様々なページに遷移しています。これは訪問者がサイト内で目的を探しにくい構造になっている可能性があります。ページやリンクを整理する等、目的ページを見つけやすくしてみてはいかがでしょうか。" res.append(dict(date=str(dt.date.today()), text=text)) elif follow_page_ratio > 0.8: text = u"トップページ(/)の次に遷移しているページは、多くが、「" + \ following[0]['page'] + \ u"」へ遷移しているようです。意図したページに遷移していない場合は、リンクの位置や見せ方を改良してみてはいかがでしょうか。" res.append(dict(date=str(dt.date.today()), text=text)) except: pass try: # TOPページへのリンク元の偏りを判定 linkdiv = self.calcLinkDiversity() if linkdiv['num'] != 0: if linkdiv['ratio'] > 0.5 and linkdiv['total_refs'] > 30: text = u"他ウェブサイトからトップページ(/)へのアクセスにおいて、特定の" + str( linkdiv['num'])+u"リンクからのアクセスが半数以上を占めているようです。リンク元に偏りがある場合には、他のウェブサイトからのリンクを増やす施策を打ってみてはいかがでしょうか。" res.append(dict(date=str(dt.date.today()), text=text)) except: pass return res