Um mecanismo de busca muito ingênuo implementado usando Django-2.1.3, python3.6.
Sou novo no Django e não sou muito proficiente em escrita, então este código é apenas para referência.
primeira página
Paginação
Precisamos salvar um índice invertido, bem como o horário de envio, remetente, assunto, link do tópico, etc. correspondente a um tópico.
isIndexed
)Deve-se observar que adicionar um par de valores-chave não pode usar o seguinte código
word . index [ doc . id ] = num
word . save ()
deve
dic = word . index
dic [ doc . id ] = num
word . index = dic
word . save ()
Abaixo está o código para o modelo em Django
from django . db import models
class Doc ( models . Model ):
sendTime = models . DateField () # 2018-12-12 , differ from DateTimeField which can be datetime or date
sender = models . CharField ( max_length = 20 )
messageType = models . CharField ( max_length = 20 ) # Journal, conf, et al
subject = models . CharField ( max_length = 100 )
begin = models . DateField ()
deadline = models . DateField ()
subjectUrl = models . CharField ( max_length = 100 )
webpageUrl = models . CharField ( max_length = 100 )
desc = models . CharField ( max_length = 250 , default = '' )
loc = models . CharField ( max_length = 40 , default = '' )
keywords = models . CharField ( max_length = 200 , default = '' )
def __str__ ( self ):
return self . subjectUrl
import json
class Wordindex ( models . Model ):
word = models . CharField ( max_length = 45 )
# model to store a list, another way is to create a custom field
_index = models . TextField ( null = True )
@ property
def index ( self ):
return json . loads ( self . _index )
@ index . setter
def index ( self , li ):
self . _index = json . dumps ( li )
def __str__ ( self ):
return self . word
class File ( models . Model ):
doc = models . OneToOneField ( Doc , on_delete = models . CASCADE )
content = models . TextField ( null = True )
isIndexed = models . BooleanField ( default = False )
def __str__ ( self ):
return 'file: {} -> doc: {}' . format ( self . id , self . doc . id )
A primeira é a página inicial. Sua estrutura é a seguinte:
< TBODY >
< TR VALIGN = TOP >
< TD > 03-Jan-2019 </ TD >
< TD > conf. ann. </ TD >
< TD > marta cimitile </ TD >
< TD > < A HREF =" http://www.cs.wisc.edu/dbworld/messages/2019-01/1546520301.html " rel =" nofollow " > Call forFUZZ IEEE Special Session </ A > </ TD >
< TD > 13-Jan-2019 </ TD >
< TD > < A rel =" nofollow " HREF =" http://sites.ieee.org/fuzzieee-2019/special-sessions/ " > web page </ A > </ TD >
</ TR > </ TBODY >
Existem regularidades e podem ser extraídas diretamente. Durante a implementação, usei o pacote BeautifulSoup do python para extrair.
Durante o uso, a chave é passar o analisador. Tentei o html, mas houve um problema com o lxml. Por fim, usei o html5lib.
Depois, há a quarta coluna (ou seja, a quarta tag td) na tabela acima, onde a tag <a>
é o link para a página web onde o tópico está localizado.
Como o tempo e o local têm padrões gerais, os padrões comuns podem ser listados e combinados usando expressões regulares
Usando o algoritmo textrank, eu mesmo implementei primeiro um algoritmo textrank muito básico, mas o efeito foi muito ruim. Mais tarde, usei a versão oficial do text-rank.
Esta parte é baseada no princípio do índice invertido, segmentando o texto da página web em palavras, removendo sinais de pontuação, etc., e depois usando o modelo de banco de dados apresentado acima para armazenar o índice invertido.
Primeiro, abaixo do título há uma linha de opções, que podem ser classificadas de acordo com esses campos. Depois, há um botão de atualização na próxima linha e um formulário de envio de pesquisa.
O conteúdo a seguir são os resultados da pesquisa organizados usando div
.
Cada resultado contém um título, palavras-chave, hora, local e resumo.
Aqui eu mesmo implementei o algoritmo tf-idf
para classificar os resultados.
def tfidf ( words ):
if not words : return docs
ct = process ( words )
weight = {}
tf = {}
for term in ct :
try :
tf [ term ] = Wordindex . objects . get ( word = term ). index
except Exception as e :
print ( e )
tf [ term ] = {}
continue
for docid in tf [ term ]:
if docid not in weight :
weight [ docid ] = 0
N = len ( weight )
for term in ct :
dic = tf [ term ]
for docid , freq in dic . items ():
w = ( 1 + log10 ( freq )) * ( log10 ( N / len ( dic ))) * ct [ term ]
if term in stopWords :
w *= 0.3
weight [ docid ] += w
ids = sorted ( weight , key = lambda k : weight [ k ], reverse = True )
if len ( ids ) < 8 : pass #???
return [ Doc . objects . get ( id = int ( i )). __dict__ for i in ids ]