https://github.com/bitcs-information-retrieval-2021-2022/project1-lumos
project1-lumos created by GitHub Classroom
https://github.com/bitcs-information-retrieval-2021-2022/project1-lumos
Science Score: 36.0%
This score indicates how likely this project is to be science-related based on various indicators:
-
○CITATION.cff file
-
✓codemeta.json file
Found codemeta.json file -
✓.zenodo.json file
Found .zenodo.json file -
○DOI references
-
✓Academic publication links
Links to: sciencedirect.com, springer.com, acm.org -
○Academic email domains
-
○Institutional organization owner
-
○JOSS paper metadata
-
○Scientific vocabulary similarity
Low similarity (1.7%) to scientific vocabulary
Repository
project1-lumos created by GitHub Classroom
Basic Info
- Host: GitHub
- Owner: BITCS-Information-Retrieval-2021-2022
- Language: Python
- Default Branch: main
- Size: 9.14 MB
Statistics
- Stars: 1
- Watchers: 0
- Forks: 0
- Open Issues: 0
- Releases: 0
Metadata Files
README.md
project1-lumos
爬虫模块
一、模块要求
1. 课堂要求
- ACM必选,要保证爬到的论文中有一定比例的视频,可以是在线观看视频的url地址,也可以是下载视频到本地后的文件路径
- Springer必选
- ScienceDirect必选,要求包含多领域的数据
- 图书馆数据源为可选加分项
- 爬到的数据必须存储到MongoDB中,字段定义详见
db_fields.md - 数据源越丰富越好,当从不同数据源爬取到相同论文时,需要去除重复数据
从每个数据源获取的数据需要具有完备性,即爬取数据量占全站数据量的比例越高越好
要求搭建一个完整的爬虫框架,在爬取不同的数据源时,只需要根据实际情况,手写少量解析网页的部分,即数据源是可插拔的。此处推荐Python Scrapy爬虫库
要求实现增量式爬取,定时更新
要求爬虫至少采用如下技术手段:
- 当爬取一个规模较大的网站时,采用某种策略/顺序,保证爬取结果不重不漏
- 使用多线程/多进程等技术提升爬虫效率
- 使用ip池、调整等待时间等技术抵御网站反爬
- 如果网络崩溃,能够从断点续爬
- 使用日志技术实时展示爬取进度
搭建一个基本的Elasticsearch+Kibana检索系统,对爬取的数据建立索引,方便展示
二、小组成员及分工
hide
三、爬虫内容及统计信息
| 网站 | 论文总量 | 视频数量 | pdf数量 | IP池 | 线程池 | 增量式 | | ---- | ---- | ---- | ---- | ---- | ---- | ---- | | ACM | 38195 | 1901 | 16659 | ✔ | ✔ | ✔ | | Springer | 7253 | 0 | 6474 | ✔ | ✔ | ✔ | | ScienceDirect | 2417 | 0 | 1213 | ✔ | ✔ | ✔ |
四、基础爬虫模块说明
该部分分别对ACM,Springer,ScienceDirect三个网站的所有信息的爬取进行说明,包括代码目录结构、代码必要说明、部署过程、启动运行流程、依赖的第三方库及版本。
1. ACM
基于request+beautifulsoup开发,高效率爬取https://dl.acm.org/ 网站上的论文,支持爬取论文的基本信息,对应pdf和视频,支持增量式爬取,使用了代理和ip池等技术
1.1 依赖的第三方库
requests==2.20.0 pymongo==3.12.1 psutil==5.8.0 tqdm==4.62.3 beautifulsoup4==4.10.0
1.2 代码结构
./ACM
├── README.md
├── basicInfo.log
├── url.log
└── utils
├── ACMUrlsCrawler.py
├── ContentDownloader.py
├── PDFDownloader.py
├── VideoDownloader.py
├── LevelUrls.py
└── GetProxy.py
1.3 运行代码
bash
cd utils
python ACMUrlsCrawler.py # 爬取论文的url
python ContentDownloader.py # 爬取论文的基本信息
python PDFDownloader.py # 爬取论文的PDF
python VideoDownloader.py # 爬取论文的video
1.4 工作流程
- 从网站 ACM 获取到所有论文的url并存入数据库,采用深度搜索的方式
- 对于第1步中获取到的论文url, 发送request的get请求获取论文的标题,作者,摘要,发布组织,年份,pdf的url,代码的url,视频url等相关信息,保存至mongodb中,并将pdf和视频的url保存至对应表中
- 为了实现增量式爬取,我们给论文的url设置了visit字段,标记该论文的基本信息是否爬去过,同时在论文信息中设置pdf和video的visit字段,用来标记pdf和video是否已经爬取下来
- 由于视频以及pdf网站被墙以及反爬虫的策略,我们采用了IP池和随机等待时间技术
1.5 一些注意事项
- 因为 ACM 网站是动态网站,所以借用谷歌浏览器的驱动插件来实现模拟人滑动浏览器,等到网页全部加载出来,再爬取里面的内容,如此就不会导致爬取的内容缺失
- journals 和 browse 两种类型的论文爬取方式不太一样:journals类型的论文总共有63个二级页面,所以以一个二级页面为分界,爬取该二级页面下的所有论文的url,然后存储到数据库中,同时把该二级页面的url存储到数据库中,如此就可以保证程序中断后重新开始爬虫时,可以跳过这个爬取过的二级页面browse 类型的论文以一个期刊的一个翻页为分界,一般一个翻页里有20篇论文,爬取这20篇论文的url并存储到数据库中,同时把该二级页面的url存储到数据库中,如此就可以保证断点续爬
2. Springer
基于request+beautifulsoup进行开发,高效率爬取 Springer 网站上的论文,支持爬取论文的基本信息和pdf,支持增量式爬取。
2.1 依赖的第三方库
requests==2.20.0 pymongo==3.12.1 psutil==5.8.0 tqdm==4.62.3 beautifulsoup4==4.10.0
2.2 代码结构
./Springer
├── basicInfo.log
├── url.log
└── utils
├── SpringerUrls.py
├── SpringerContent.py
├── PDFDownloader.py
├── config.py
└── GetProxy.py
2.3 运行代码
bash
cd utils
python SpringerUrls.py # 爬取论文的url
python SpringerContent.py # 爬取论文的基本信息
python PDFDownloader.py # 爬取论文的PDF
2.4 工作流程
- 从网站 Springer 获取到所有论文的url并存入数据库,采用深度搜索的方式
- 对于第1步中获取到的论文url, 发送request的get请求获取论文的标题,作者,摘要,发布组织,年份,pdf的url,代码的url等相关信息,保存至mongodb中,并将pdf的url保存至对应表中
- 为了实现增量式爬取,我们给论文的url设置了visit字段,标记该论文的基本信息是否爬去过,同时在论文信息中设置pdf的visit字段,用来标记pdf是否已经爬取下来
- 为解决网站登录问题,我们使用了cookie
2.5 一些注意事项
- 对于 Springer 网站的登录机制,我们使用了cookie
- journals 和 conferece 两种类型的论文由于网页html构造不同,因此使用了不同的函数分别对两种类型的论文网页进行解析。其中,SpringerUrls.py中的getConferencefromTopLevel函数用来爬取 conferece 类型的论文,getJournalfromTopLevel函数用来爬取 journal 类型的论文,在运行时可以加以区分
- Springer 网站的部分论文需要付费购买,因此暂时无法对这部分论文进行爬取
3. ScienceDirect
基于request+beautifulsoup进行开发,高效率爬取 ScienceDirect 网站上的论文,支持爬取论文的基本信息和pdf,支持增量式爬取。
3.1 依赖的第三方库
requests==2.20.0 pymongo==3.12.1 psutil==5.8.0 tqdm==4.62.3 beautifulsoup4==4.10.0
3.2 代码结构
./ScienceDirect
├── basicInfo.log
├── url.log
└── utils
├── SciDirUrlsCrawler.py
├── ContentManager.py
├── PDFManager.py
├── LevelUrls.py
├── config.py
└── GetProxy.py
3.3 运行代码
bash
cd utils
python SciDirUrlsCrawler.py # 爬取论文的url
python ContentManager.py # 爬取论文的基本信息
python PDFManager.py # 爬取论文的PDF
3.4 工作流程
- 从网站 ScienceDirect 获取到所有论文的url并存入数据库,采用深度搜索的方式
- 对于第1步中获取到的论文url, 发送request的get请求获取论文的标题,作者,摘要,发布组织,年份,pdf的url,代码的url等相关信息,保存至mongodb中,并将pdf的url保存至对应表中
- 为了实现增量式爬取,我们给论文的url设置了visit字段,标记该论文的基本信息是否爬去过,同时在论文信息中设置pdf的visit字段,用来标记pdf是否已经爬取下来
- 由于网站被墙以及反爬虫的策略,我们采用了IP池和随机等待时间技术
3.5 一些注意事项
- 因为 ScienceDirect 网站是动态网站,所以借用谷歌浏览器的驱动插件来实现模拟人滑动浏览器,等到网页全部加载出来,再爬取里面的内容,如此就不会导致爬取的内容缺失
- 因为 ScienceDirect 网站的pdf网页对应的url有两种形式,请求第一种形式只能获得网页的html代码,所以同样需要借助谷歌浏览器的驱动插件来实现模拟人滑动浏览器,等到网页全部加载出来,形成pdf对应的url,在进行request请求获取pdf文件
- 由于 ScienceDirect 网站的部分pdf北理没有权限获取,故没有爬取这一部分的pdf文件
五、性能提升模块说明
该部分分别对IP池、线程池和增量式的实现进行相关说明
1. 线程池
由于项目爬取时单线程的爬取速度慢,会耗费过多时间,所以本项目实现了线程池进行并发爬虫,具体应用到视频和pdf的下载过程中。
1.1 关于线程池的选取
使用threadpool模块进行线程池的实现。以ACM中视频的下载为例,我们声明了一个指定大小的线程池,通过一个方法downloadVideo()和一组参数args来构造请求,再将这些请求全部放进线程池里,此时,线程池会自动等待这些请求执行完毕。
1.2 依赖
python
import threadpool
1.3 相关函数使用
python
def run(self, poolSize=2):
count = len(self.VideoUrl)
# print(count)
# 构造线程参数
args = []
for index in range(0, count):
args.append((None, {'url': self.VideoUrl[index]}))
# 线程池大小
if count < poolSize:
poolSize = count
# 构造线程池
pool = threadpool.ThreadPool(poolSize)
requests = threadpool.makeRequests(self.downloadVideo, args)
[pool.putRequest(req) for req in requests]
pool.wait()
1.4 工作模式
- ACM:线程池爬取视频。
- Springer:线程池爬取pdf。
- ScienceDirect:线程池爬取pdf。
2. IP Pool
由于项目爬取的网站中有视频以及PDF的下载需求,并且由于目标网站的特殊性,项目需要同时具有防止反爬虫的能力。因此,本项目从提供ip代理的五个网站爬取可用的ip来实现IP池,让爬虫更加高效可用。
2.1 相关代码
本部分的实现在各项目中的GetProxy.py文件中。其中用于返回ip的函数为:
python
def getProxy(key)
2.2 工作模式
在需要使用ip池的py程序中import这个py程序,调用getProxy函数,传递的参数为一个1-5的随机数
获得函数返回的一个ip代理
在request.get()中添加参数proxies=返回的ip即可实现ip代理
3. 增量式爬取
由于目标网站经常新增页面,本项目采取增量式爬虫,定期从网站上爬取新的论文信息。
3.1 工作模式
- 增量式改进分为两部分,一是定期爬取,选择apscheduler库的定时任务实现。
python
sched = BlockingScheduler()
sched.add_job(run_spider, 'cron', hour=10, minute=0)
sched.start()
- 另一部分是去重,本项目的具体方法是将论文的url、pdf的url和视频的url保存在在mongo数据库中,并为每条url数据设置visit字段。在爬取论文时检查url是否已经爬取,并在下载时根据visit字段判断内容是否已经下载。
去重代码主要实现于以下函数中:
.
SpiderForACL/utils/ACLUrlCrawler/saveUrls, SpiderForACL/utils/ACLUrlCrawler/getUnvisitedUrls, SpiderForPwC/utils/UrlCrawler/saveUrls, SpiderForPwC/utils/PDFDownloader/addUrl, scrapy/crossminds_saver/save_paperinfo
3.2 运行方法
直接运行根目录下ACLInc.py,PwCInc.py,CrossMindInc.py,即可每天按时爬取新论文。 ``` python ACLInc.py python CrossMindInc.py python PwCInc.py ```
3.3 依赖
apscheduler==3.6.3
datetime
六、检索模块
1 搭建
1.1 环境依赖
ElasticSearch-7.15.2
Kibana-7.15.2
Python libraries:
elasticsearch
pymongo
在服务器端安装好指定版本的ElasticSearch以及Kibana,并通过修改配置文件完成Kibana与ElasticSearch的连接。
默认情况下,ElasticSearch的链接端口为localhost:9200,Kibana的端口是localhost:5601。
1.2 代码结构
./search
├── config_retrieval
├── index_template.json
└── insert.py
1.3 数据库连接
通过pymongo连接MongoDB,读取数据库中存储好的论文信息,其中主要读取的是ACMBasicInfo、SpringerBasicInfo和SciDirBasicInfo三个表。
为实现MongoDB到ElasticSearch的数据迁移,需要连接MongoDB数据库。通过修改配置文件config_retrieval,实现对数据库的灵活控制,其中可能的需要修改的数据包括:
db = paper //数据库名称
host = 10.108.18.24 //数据库所在服务器地址
port = 27017 //访问数据库端口
2 创建索引及数据迁移
2.1索引创建
ElasticSearch内部采用索引(Index)的结构存储数据, 可以通过修改indextemplate.json达到修改索引结构从而实现对ElasticSearch中数据的检索功能修改的目的。 对于字符串型的数据,分成text和keyword两种类型,其中keyword用于可视化情景筛选聚合,text用于全文检索。 其中默认索引设置如下: ``` { "settings": { "analysis": { "normalizer": { "mynormalizer": { "type": "custom", "filter": ["lowercase", "asciifolding"] } } } }, "mappings": { "properties": { "title": { "type": "text", "index": "true", "normalizer": "my_normalizer" }, "abstract": { "type": "text", "index": "true"
},
"authors": {
"type": "keyword",
"index": "true",
"normalizer": "my_normalizer"
},
"doi": {
"type": "text",
"index": "false"
},
"url": {
"type": "text",
"index": "false"
},
"year": {
"type": "integer"
},
"month": {
"type": "text"
},
"type": {
"type": "keyword"
},
"venue": {
"type": "keyword"
},
"source": {
"type": "keyword"
},
"video_url": {
"type": "text"
},
"video_path": {
"type": "text"
},
"thumbnail_url": {
"type": "text"
},
"pdf_url": {
"type": "text"
},
"pdf_path": {
"type": "text"
},
"inCitations": {
"type": "long"
},
"outCitations": {
"type": "long"
}
}
}
}
```
2.2运行方法
执行如下指令即可完成ElasticSearch索引创建以及数据迁移。
python insert.py
3 可视化
运行Kibana并访问localhost:5601即可进行检索和数据可视化分析。
可视化界面展示来自不同站点的论文数目,不同年份的论文示例

可视化界面展示作者云图以及期刊和会议论文比例示例

执行检索结果示例

Owner
- Name: BITCS-Information-Retrieval-2021-2022
- Login: BITCS-Information-Retrieval-2021-2022
- Kind: organization
- Repositories: 1
- Profile: https://github.com/BITCS-Information-Retrieval-2021-2022