方 煒
(安徽師范大學圖書館 安徽蕪湖 241003)
圖書采購查重是指對海量的館藏文獻資源與計劃采購的文獻列表進行篩選、去重,避免因重復采購而造成資源的浪費。這在圖書館資源建設過程中是非常重要的一環(huán),但也是圖書館采訪人員長期以來面臨的難點。因為圖書查重是一種勞力密集的重復性工作,既簡單又枯燥,必須耗費大量的人力和時間,同時采訪人員長時間進行重復單調(diào)的工作,很容易產(chǎn)生漏檢和錯檢[1]。目前業(yè)界出現(xiàn)了多種查重方法和查重系統(tǒng),各有優(yōu)劣。筆者通過分析現(xiàn)有查重方法和系統(tǒng)的使用效果,針對其不足之處,設計了一套基于Python語言以及PyQt工具包的圖書采購查重系統(tǒng)。
采訪工作中的查重,實際上是將兩個書目信息列表進行比對的過程,現(xiàn)有館藏書目(以下簡稱“源書目”)信息一般存儲在各圖書館數(shù)據(jù)庫中,而計劃采購書目(以下簡稱“目標書目”)信息一般為圖書館自搜集的書目清單,或由書商提供的書目清單。從技術層面來看,目前常見的查重方式有以下3種:①圖書管理系統(tǒng)。圖書館在文獻資源建設時一定會使用圖書管理系統(tǒng),而大多數(shù)管理系統(tǒng)如ILAS、ALEPH 500中已經(jīng)集成了采訪查重功能,因此部分圖書館直接通過其正在使用的圖書管理系統(tǒng)進行查重。②工具系統(tǒng)。在圖書管理系統(tǒng)無法充分滿足自身查重需求時,部分圖書館采用內(nèi)部開發(fā)或購買獨立的查重工具系統(tǒng)的方式進行查重。③人工比對。早期,在圖書館數(shù)字化建設還不夠成熟的時候,人工比對是唯一的查重方式,但是隨著館藏資源數(shù)量的劇增,純粹意義上的人工比對方法已經(jīng)無法實施。但是針對某些信息不規(guī)范或殘缺的特殊文獻,采訪人員需進行人工主觀鑒別,再進行查重。
以上提到的3種查重方式仍然廣泛應用在圖書館的采訪工作中,其使用環(huán)境和查重效率方面各有優(yōu)劣。
1.2.1 圖書管理系統(tǒng)
圖書管理系統(tǒng)工作過程是圖書管理系統(tǒng)自動分析采訪人員上傳的目標書目文件,進行數(shù)據(jù)庫比對,并由管理系統(tǒng)自動輸出結(jié)果。這種方法要求目標書目文件格式規(guī)范,滿足系統(tǒng)輸入要求,且比對項符合系統(tǒng)規(guī)則,可以被系統(tǒng)正常識別。
圖書管理系統(tǒng)查重的優(yōu)點為:實時準確。因為是直接訪問源數(shù)據(jù)庫,其信息都是實時的,不會出現(xiàn)信息滯后,查詢結(jié)果準確。其缺點為:①依賴網(wǎng)絡。無論采訪人員在館內(nèi)還是館外,都必須具有網(wǎng)絡訪問權(quán)限,且要求網(wǎng)絡快速穩(wěn)定,否則將造成無法訪問或查重效率低下等問題。②靈活性差。系統(tǒng)對目標書目文件的格式有著嚴格的要求,且查重字段也必須完全相同,但工作人員從各種渠道獲得的目標書目文件格式各異,所以需先進行整理和轉(zhuǎn)換后才能進行查重。③可維護性差。常見的系統(tǒng)都是商業(yè)公司的產(chǎn)品,如果采訪人員需要根據(jù)特定的場景自定義查重方法,很難單獨要求其修改功能,即便進行了修改,在升級系統(tǒng)時也難免會影響到其他功能的正常使用。
1.2.2 工具系統(tǒng)
目前常用的工具系統(tǒng)主要分為B/S架構(gòu)和C/S架構(gòu)。如果圖書管理系統(tǒng)提供了對外訪問接口,兩種架構(gòu)都可以進行遠程實時查重,區(qū)別不大。但在沒有訪問接口時,B/S架構(gòu)的系統(tǒng)一般是先將源數(shù)據(jù)庫導出備份到服務器上,再連接查詢備份的數(shù)據(jù)庫。而C/S架構(gòu)的系統(tǒng)則是從源數(shù)據(jù)庫中導出Excel、MARC等格式的備份文件,然后再利用讀取文件信息的方式解析其中包含的書目信息,進行比對后輸出結(jié)果。
工具系統(tǒng)查重的優(yōu)點為:①靈活性高。工具系統(tǒng)在研發(fā)設計時針對性較強,完全為采訪查重工作服務,可以充分滿足采訪人員的查重需求。②易維護。因為是獨立的工具系統(tǒng),所以易于修改和擴展,及時滿足采訪人員的工作需求,具有更多的靈活性,而且不用擔心會影響到圖書管理系統(tǒng)。其缺點為:①實時性受限。如果圖書管理系統(tǒng)提供了接口,查詢結(jié)果具有實時性。反之,因為是備份數(shù)據(jù),所查詢出的結(jié)果具有滯后性。②需要技術支持。無論是導出到備份數(shù)據(jù)庫或是本地文件,都需要相關技術人員的操作,后期的擴展和維護更是需要技術支持。
1.2.3 人工比對
針對某些特定文獻或特殊場景,人工查重是一個更加主觀準確的查重方式。采訪人員首先利用自身專業(yè)知識和工作經(jīng)驗對目標書目進行信息提取和分類,再逐條輸入到圖書管理系統(tǒng)中查詢,并對最終的查重結(jié)果做出修改和確認。
人工比對查重的優(yōu)點為:靈活性高。采訪人員可以主觀分辨出相似的書目,也可以根據(jù)經(jīng)驗對記錄有誤的信息進行人工糾錯等。其缺點為:①效率低。在目標書目數(shù)量較為龐大的情況下,人工比對的速度慢,需要耗費大量時間完成。②易產(chǎn)生誤差。因為是人工比對,難免會因為工作疲勞或疏忽而導致結(jié)果出現(xiàn)偏差。
通過上面的優(yōu)劣對比,筆者認為工具系統(tǒng)查重是三者中最為方便、靈活的查重方式。不僅可以在不影響源數(shù)據(jù)庫的情況下進行操作,還可以利用其可擴展性充分滿足采訪人員的工作需求,其效率和準確度上也為最優(yōu)。其中,C/S架構(gòu)的系統(tǒng)比B/S架構(gòu)的系統(tǒng)更為合適,理由如下:①易于安裝部署。B/S架構(gòu)的系統(tǒng)必須安裝數(shù)據(jù)庫軟件,而數(shù)據(jù)庫軟件本身又比較龐大,不便于安裝,而且需要進行配置部署后才能訪問。相反,C/S架構(gòu)的系統(tǒng)安裝程序體積小,無需配置部署,直接操作交互界面即可使用。②適用場景廣泛。B/S架構(gòu)的系統(tǒng)一般都部署在固定的服務器上,必須通過網(wǎng)絡遠程訪問。而C/S架構(gòu)的系統(tǒng)則不僅可以通過網(wǎng)絡訪問遠程數(shù)據(jù)庫,也可以在無網(wǎng)絡的環(huán)境下直接操作本地備份文件,適用于館內(nèi)館外的各種場景。
Python是一門應用廣泛的通用編程語言,易于學習使用且功能強大,適合各種規(guī)模的軟件編寫[2]。其文件處理功能也非常強大。例如,可以使用xlrd、xlwt模塊對Excel文件進行讀寫;利用xml.dom模塊對XML文件進行讀寫等。此外,針對超大文件,Python還可以進行分塊讀取,很好地解決了內(nèi)存不足等問題。
Qt庫是目前最強大的GUI庫之一,而PyQt作為一個強大的工具包,成功地將腳本語言Python和Qt庫融合到了一起,利用它可以很方便地創(chuàng)建GUI應用程序[3]。這是實現(xiàn)查重系統(tǒng)中用戶交互界面模塊最佳的方案。
因此,本查重系統(tǒng)是基于Python語言,再結(jié)合PyQt工具包進行開發(fā),最終生成了一個Windows環(huán)境下的安裝程序,采訪人員直接進行單機安裝即可投入使用。
采訪人員在查重時的工作流程一般分為4個步驟:①輸入源書目信息以及目標書目信息。這些信息一般以文件的形式呈現(xiàn),如Excel文件、MARC格式的.marc文件或.iso文件等。②選定需要進行比對的字段。書目信息一般包含多個字段,但因存儲方式不同,各字段又無法一一對應,因此要人工選取合適的字段進行比對。③執(zhí)行查重。查重系統(tǒng)根據(jù)輸入的文件信息,以及采訪人員選定的字段進行自動比對。④輸出結(jié)果。待查重系統(tǒng)運算完畢之后,根據(jù)采訪人員指定的結(jié)果存儲方式,將結(jié)果輸出到本地文件中。
2.3.1 文件讀取
通過調(diào)查采訪人員的工作過程發(fā)現(xiàn),采訪人員存儲書目信息的文件格式一般為Excel文件或者MARC格式的.marc文件和.iso文件,其中MARC作為機讀目錄格式的大統(tǒng)一,借其數(shù)據(jù)格式的標準化及細分化優(yōu)勢,廣泛應用于各類圖書館的編目工作中,在采訪工作中也是主流文件[4]。因此,查重系統(tǒng)中應該具備讀取并解析這些文件格式的功能模塊。此外,還需要考慮到源書目文件較大,可能是GB級別的文件,而一般的計算機閑置內(nèi)存可能只有幾百MB,如果全部直接加載到內(nèi)存,系統(tǒng)可能會因為內(nèi)存耗盡而無響應等問題,需要確保此功能模塊可以處理大文件。
2.3.2 解析字段
常見的查重比對都是只比較ISBN字段,但是為了讓采訪人員可以更靈活地比對書目信息,本系統(tǒng)將提供字段解析模塊,首先應分析文件的類型,再用不同的方式獲取其字段信息。例如,Excel文件中,其字段信息一般為每個Sheet中第一行的數(shù)據(jù);而MARC格式的字段則是和數(shù)據(jù)一起存放在每個條目中。
因為存在多種文件格式,所以對應字段的存儲方式存在差異。例如,MARC字段中代表出版社的字段為“010”,子字段“b”,而在Excel文件中,字段名稱直接存儲為字符串“出版社”,無法直接進行比較。因此本模塊將采用配置文檔的方式,使得用戶可以自定義MARC字段表示的名稱,從而實現(xiàn)不同類型文件之間的查重。
2.3.3 比對查重
根據(jù)采訪人員選擇需要比對的字段信息,采用遍歷的方式,提取源書目和目標書目中被選字段對應的數(shù)據(jù),最后再通過字符串比對的方式進行查重。但是如果直接字符串比對,又無法兼容一些可能存在的問題。例如,2007年起使用的新版ISBN號是13位,而在此之前都是使用10位來表示,對于同一本書的新舊表示方法,必須在比對時要考慮到兼容性[5]。此外還有字符串中存在多余空格、大小寫等問題也將在本模塊中考慮到。
2.3.4 輸出結(jié)果
對于采訪工作人員來說,最終的查重結(jié)果一般為方便存儲、閱讀的本地文件。因此,本系統(tǒng)擬將結(jié)果寫入到新創(chuàng)建的Excel文件中,并分成重復列表和非重復列表兩個工作Sheet,采訪人員可以直接用Office軟件打開查看。其中重新創(chuàng)建Excel文件的方式可以保證原始文件不會被損壞。
本系統(tǒng)的開發(fā)IDE選為PyCharm。PyCharm是一款功能強大的Python編輯器,帶有一整套可以幫助用戶在使用Python語言開發(fā)時提高其效率的工具,且具有跨平臺性[6]。
文件讀取功能的實現(xiàn)主要使用的是I/O函數(shù)、xlrd和xml.dom模塊:
# Read and parse MARC file
class MARCHelper(object):
def __init__(self,file_path):
self._file = open(file_path,'rb')
… …
# Read and parse Excel file
class ExcelHelper(object):
def __init__(self,file_path):
self._ file_data = xlrd.open_workbook(_file_path,use_mmap=0,on_demand=True)
… …
# Read and parse config file(.xml)
class MARCFiledManager:
def __init__(self,file_path):
self.file_dom = xml.dom.minidom.parse(file_path)
… …
Excel文件讀取字段的方式為直接讀取第一張工作Sheet的第一行內(nèi)容:
… …
def get_column_names(self):
column_names = self.get_row_value(0,0)
return column_names
… …
針對MARC文件的方式則為解析字段以及子字段標識符,再通過比對XML格式配置文檔里的信息,找到對應的字段名稱[7]。其中配置文件的格式如下:
… …
… …
采訪人員可以根據(jù)需求自行修改配置文件中的字段名稱,以便更靈活地進行字段比對。
比對方面,設計時采用了面向?qū)ο笾卸鄳B(tài)的概念,在處理Excel文件的ExcelHelper類,以及處理MARC文件的MARCHelper類中,定義了相同的check_row_exist函數(shù):
def check_row_exist(self,compared_columns_index,tar_value,tar_columns_index):
除此之外,還定義了一個遍歷書目信息的迭代器,可以循環(huán)讀取數(shù)據(jù):
… …
def set_iter_begin(self):
… …
def get_iter(self):
… …
def next_iter(self):
… …
查重時迭代器的使用方法如下:
self.__instance_tar_file_helper.set_iter_begin()
iter_not_end = self.__instance_tar_file_helper.next_iter()
while iter_not_end:
… …
iter_not_end = self.__instance_tar_file_helper.next_iter()
其中,Excel數(shù)據(jù)以讀到最后一張工作Sheet的最后一行作為結(jié)束,MARC文件則是讀到空行作為結(jié)束。
由于數(shù)據(jù)量可能較大,比對過程將需要很長的時間,所以必須采用多線程的方式進行比對操作,否則主交互界面將會卡死,導致程序崩潰,用戶交互也不夠友好。因此在實現(xiàn)此功能時繼承了QThread類,并采用Signal與Slots的方式讓數(shù)據(jù)處理層和UI層進行通訊:
… …
class GetDuplicateColumnNamesThread(QtCore.QThread):
GetDuplicateColumnNames_Finished_Signal= QtCore.pyqtSignal(list)
… …
class CheckAndSaveThread(QtCore.QThread):
CheckAndSave_Finished_Signal = QtCore.pyqtSignal()
… …
為了方便閱讀,最終的結(jié)果是存儲到Excel文件中,所以采用的是xlwt模塊,為此代碼中專門定義了一個ExcelSaver類,并新建一個文件:
class ExcelSaver(object):
def __init__(self):
self._work_book = xlwt.Workbook()
進行比對之前會先建立兩個工作Sheet,即重復的和非重復的,并寫入列名:
… …
excel_saver = ExcelSaver()
excel_saver.add_sheet(u'非重復')
excel_saver.add_sheet(u'重復')
column_names = self.__instance_tar_file_helper.get_column_names()
excel_saver.insert_row(u'重復',0,column_names)
excel_saver.insert_row(u'非重復',0,column_names)
… …
比對過程中會自動插入數(shù)據(jù),在結(jié)束時進行保存:
… …
if duplicate:
excel_saver.append_row(u'重復',tar_value)
else:
excel_saver.append_row(u'非重復',tar_value)
… …
excel_saver.save(result_file_path)
… …
本系統(tǒng)的UI界面是先使用Qt Designer創(chuàng)建并設置好所有控件,再轉(zhuǎn)換為Python文件,效果如圖1所示。

圖1 UI界面效果圖
UI上用兩個QLineEdit分別表示源書目和目標書目的文件路徑,并提供QFileDialog方便用戶選擇文件。
在用戶設置完路徑并點擊顯示列名后,UI下方采用QTableWidget來顯示可以進行比對的字段,以及可以讓用戶勾選的CheckBox。
用戶選擇完畢后直接點擊QPushButton實現(xiàn)的查重按鈕,會出現(xiàn)讓用戶選擇保存結(jié)果文件的對話框,然后即開始進行查重。查重的同時UI界面的中間會出現(xiàn)一個模態(tài)等待對話框。
… …
class WaitingDialog(QtWidgets.QDialog):
def __init__(self,parent=None):
QtWidgets.QDialog.__init__(self,parent)
self.setWindowTitle('Please wait...')
self.setWindowFlag(QtCore.Qt.SplashScreen)
… …
待查重完畢之后,會有對話框提示用戶操作完成,此時用戶可以打開保存的文件,閱讀查重結(jié)果。
在進行UI界面的設計時,也考慮到了采訪人員所用系統(tǒng)語言環(huán)境的問題,將要顯示的文字都進行了國際化處理,程序可以自動識別當前系統(tǒng)的語言,顯示對應的語言文字:
… …
def translate_ui(self,BookListCheckerClass):
_translate = QtCore.QCoreApplication.translate
BookListCheckerClass.setWindowTitle(_trans late("BookListCheckerClass","圖書查重系統(tǒng)"))
self.label_source_books.setText(_translate("BookListCheckerClass","現(xiàn)有圖書:"))
… …
本系統(tǒng)的設計和實現(xiàn)采用了目前較為前沿的Python語言和Qt框架,充分發(fā)揮了其文件處理功能和GUI搭建功能,為后來圖書采購查重系統(tǒng)的開發(fā)選擇提供了參考,推動了圖書采購查重自動化的發(fā)展。總體來看,具有以下優(yōu)點:①易安裝使用。系統(tǒng)的安裝程序大小在35MB以內(nèi),易于攜帶和安裝。采訪人員無需網(wǎng)絡,無需配置數(shù)據(jù)庫等操作,即可隨時使用。對于經(jīng)常在外采購圖書的工作人員非常適用。②支持文件類型豐富。為了充分滿足查重需求,本系統(tǒng)在文件類型的支持上涵蓋了常用的.xls、.xlsx、.iso、.marc等書目信息格式。③比對靈活。不僅可以讓用戶復選比對字段,還考慮到了ISBN的兼容性問題、Excel字段和MARC字段不對應的問題,并允許用戶進行自定義字段,使得系統(tǒng)可以更靈活地滿足查重需求。④系統(tǒng)可移植性高。本系統(tǒng)所采用技術,無論是Python還是Qt都是跨平臺的,其可移植性高,可以不僅僅依賴于Windows操作系統(tǒng)。
本系統(tǒng)依然存在不足之處。例如,文件類型的支持雖然已經(jīng)滿足常用的需求,但是還可以進一步擴大,如.txt和.cvs等格式的文件。另外,本系統(tǒng)雖然在設計上已經(jīng)預留了網(wǎng)絡查詢接口,但在實現(xiàn)上還沒有全部完成,暫時沒能彌補其實時性差的缺點。希望在后續(xù)的工作中可以繼續(xù)完善該系統(tǒng),更好地為查重工作提供自動化服務。