محرك بحث ساذج جدًا تم تنفيذه باستخدام Django-2.1.3 وpython3.6.
أنا جديد على Django ولست ماهرًا جدًا في الكتابة، لذا فإن هذا الرمز هو للإشارة فقط.
الصفحة الأولى
ترقيم الصفحات
نحن بحاجة إلى حفظ فهرس مقلوب، بالإضافة إلى وقت الإرسال، والمرسل، والموضوع، ورابط الموضوع، وما إلى ذلك، المطابق للموضوع، لذلك قمت بتصميم بنية قاعدة البيانات التالية.
isIndexed
)تجدر الإشارة إلى أن إضافة زوج من القيمة الرئيسية لا يمكن أن يستخدم الكود التالي
word . index [ doc . id ] = num
word . save ()
يجب
dic = word . index
dic [ doc . id ] = num
word . index = dic
word . save ()
فيما يلي رمز النموذج في 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 )
الأول هو الصفحة الرئيسية وهيكلها هو كما يلي:
< 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 >
هناك حالات منتظمة ويمكن استخراجها مباشرة أثناء التنفيذ، استخدمت حزمة BeautifulSoup الخاصة ببايثون لاستخراجها.
أثناء الاستخدام، المفتاح هو تمرير المحلل اللغوي، لقد حاولت استخدام html، ولكن كانت هناك مشكلة مع lxml، وأخيرًا استخدمت html5lib.
ثم هناك العمود الرابع (أي علامة td الرابعة) في الجدول أعلاه، حيث تكون العلامة <a>
هي الرابط إلى صفحة الويب التي يوجد بها الموضوع، ويجب أيضًا استخراجها.
وبما أن الزمان والمكان لهما أنماط عامة، فيمكن إدراج الأنماط الشائعة ومطابقتها باستخدام التعبيرات العادية
باستخدام خوارزمية textrank، قمت أولاً بتنفيذ خوارزمية textrank الأساسية جدًا بنفسي، لكن التأثير كان سيئًا للغاية، ثم استخدمت الإصدار الرسمي من textrank.
يعتمد هذا الجزء على مبدأ الفهرس المقلوب، وتقسيم نص صفحة الويب إلى كلمات، وإزالة علامات الترقيم، وما إلى ذلك، ثم استخدام نموذج قاعدة البيانات المقدم أعلاه لتخزين الفهرس المقلوب.
أولاً، يوجد أسفل العنوان صف من الخيارات، والتي يمكن فرزها وفقًا لهذه الحقول، ثم يوجد زر تحديث في الصف التالي، ونموذج إرسال البحث.
المحتوى التالي هو نتائج البحث مرتبة باستخدام div
.
تحتوي كل نتيجة على عنوان وكلمات رئيسية ووقت وموقع وملخص.
لقد قمت هنا بتطبيق خوارزمية tf-idf
بنفسي لفرز النتائج، وكان الكود كما يلي
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 ]