def main(query, paper_set, num_result): # 创建mongoDB数据源管理 mgdbds = MongoDBDS(config=config) # 指定ID管理器 pim = IDManager( config=config, key=DocKeyPair('paper_id', 'title'), auto_inc=DocKeyPair('id_inc', 'paper_id') ) # 指定IEEE爬虫 ir = IEEERetrieval( query=query, offset=0, num_result=num_result, paper_id_manager=pim, paper_set=paper_set ) ir_res = ir.retrieve() # 执行检索 ir.save(mgdbds) # 将检索结果记录在数据库中 # IEEE全文爬虫+PDF解析 article_numbers = [item['IEEEArticleNumber'] for item in ir_res] pdf_parser = PDFParser() for article_number in article_numbers: # 请注意:一定要在校园网环境下爬才能成功! ifs = IEEEFulltextSpider( article_number=article_number, request_interval=5 ) ifs_result = ifs.execute() # 爬取PDF,记录爬取结果所在路径 # 当然并不是所有原文都能成功爬到的,爬不到就会输出ERROR的log # 更新数据库中对应元数据的uri字段。 # 可以整合到FullTextSpider类中,但这样会增加耦合,所以我还在思考 if ifs_result: # 解析内容并保存 content = pdf_parser.parse(ifs_result, pdf_format=PDFFormat.IEEE) mgdbds.query_and_update_doc( docset='metadata', query={'IEEEArticleNumber': article_number}, val={'$set': {'uri': ifs_result, 'content': content}} ) # 另外以后可以考虑改成多线程,这样爬IEEE的时候还能继续运行后面的程序 # 此时./data中应该已经有几篇pdf了。 # 检查现在数据库中的内容 print(mgdbds.get_db().list_collection_names()) print(list(mgdbds.get_db()['paper_id'].find())) print(list(mgdbds.get_db()['paper_set'].find())) print(list(mgdbds.get_db()['metadata'].find())[-1]) # 注意uri字段 print(list(mgdbds.get_db()['id_inc'].find()))
def test_multi_update(self): from data_platform.datasource.abc.doc import DocKeyPair with tempfile.TemporaryDirectory(prefix='test_', suffix='_docds') as tmpdir: ds = self.get_test_instance(tmpdir) doc_key = ds.update_doc([('pep', 'pep001'), ('pep', 'pep051'), ('pep', 'pep511')], SAMPLE_DOC2) del ds self.assertCountEqual(doc_key, [ DocKeyPair(docset_name='pep', doc_name='pep511'), DocKeyPair(docset_name='pep', doc_name='pep051'), DocKeyPair(docset_name='pep', doc_name='pep001') ])
def test_delete(self): from data_platform.datasource.abc.doc import DocKeyPair with tempfile.TemporaryDirectory(prefix='test_', suffix='_docds') as tmpdir: ds = self.get_test_instance(tmpdir) ds.create_doc(val=SAMPLE_DOC) ds.create_doc(key={('pep', 'pep484'): {}}, val=SAMPLE_DOC2) self.assertEqual(ds.delete_doc(key={('pep', 'pep484'): {}}), 1) docs = ds.read_doc() self.assertNotIn(DocKeyPair(docset_name='pep', doc_name='pep484'), docs) self.assertIn( DocKeyPair(docset_name='_default', doc_name='_default'), docs) ds.delete_doc() self.assertFalse(ds.read_doc()) del ds
def test_multi_update(self): from data_platform.datasource.abc.doc import DocKeyPair with tempfile.TemporaryDirectory(prefix='test_', suffix='_docds') as tmpdir: ds = self.get_test_instance(tmpdir) doc_key = ds.create_doc([('pep', 'pep001'), ('pep', 'pep051'), ('pep', 'pep511')], {'test_attr': True}) doc_key = ds.update_doc([('pep', 'pep001'), ('pep', 'pep051'), ('pep', 'pep511')], SAMPLE_DOC2) result = ds.read_doc(('pep', 'pep001')) self.assertCountEqual(doc_key, [ DocKeyPair(docset_name='pep', doc_name='pep511'), DocKeyPair(docset_name='pep', doc_name='pep051'), DocKeyPair(docset_name='pep', doc_name='pep001') ]) target_value = {**SAMPLE_DOC2, 'test_attr': True} self.assertEqual(result, {DocKeyPair('pep', 'pep001'): target_value}) del ds
def test_create(self): from data_platform.datasource.abc.doc import DocKeyPair with tempfile.TemporaryDirectory(prefix='test_', suffix='_docds') as tmpdir: ds = self.get_test_instance(tmpdir) r_value = ds.create_doc(val=SAMPLE_DOC) del ds self.assertEqual( r_value, [DocKeyPair(docset_name='_default', doc_name='_default')])
def test_named_create_and_read(self): from data_platform.datasource.abc.doc import DocKeyPair with tempfile.TemporaryDirectory(prefix='test_', suffix='_docds') as tmpdir: ds = self.get_test_instance(tmpdir) doc_key = ds.create_doc(key={('pep', 'pep484'): {}}, val=SAMPLE_DOC2) r_value = ds.read_doc() self.assertEqual( doc_key, [DocKeyPair(docset_name='pep', doc_name='pep484')]) self.assertEqual(r_value, {doc_key[0]: SAMPLE_DOC2}) del ds
def get_id(self, name: Text) -> int: '''如果在数据库中查到了这个name对应的id(即查找条件为{key: name}),就返回id。 如果没查到结果,为这个name分配一个新id,并加入到数据库中''' key_value_pair = DocKeyVal(self._collection, self._key, name) result = self._db.get_id(key=key_value_pair) if result is not None: # 如果在数据库中查到了这个name对应的id,就返回id。 return result # 如果数据库中没查到结果,说明本name还没有录入到数据库。 # 为这个name分配一个新id,并加入到数据库中 nextv_doc_key_pair = DocKeyPair(self._auto_inc_docset, self._auto_inc_key) new_id = self._db.get_next_value(nextv_doc_key_pair) self._db.insert_one(id_=new_id, docset=self._collection, val={self._key: name}) return new_id