写在前面
本次课堂练习,老师提出要我们做一个热词云。说实话看到的一瞬间有些懵逼,不知道要怎么做。但查阅了资料后一切明朗起来。也提示我们凡事不要怕,先做就是了。
本文web端代码已上传github:https://github.com/wushenjiang/PaperData
需求
本次任务的需求:爬取CVPR2019年所有论文的题目,并提取题目中的关键字,做成按照热度显示大小的热词云。
成品截图
成品链接:http://39.97.109.245/PaperData/papercloud.jsp
截图:
爬虫模块设计及代码
这里我起先设计了一个爬虫代码,但插入时时失败,出现莫名其妙的错误。且速度极慢。在借鉴了同学的爬虫模块后,速度依然很慢,但好歹可以插入了。也让我提高了我的python水平。代码如下:
# coding=utf-8
import pymysql
import requests
from lxml import etree
class Spider:
def __init__(self):
self.url = "http://openaccess.thecvf.com/CVPR2019.py"
self.header = {
"user-agent": "Mozilla/5.0 (Linux; Android 8.0; Pixel 2 Build/OPD3.170816.012) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.116 Mobile Safari/537.36"}
self.db = pymysql.connect(host=‘localhost‘, port=3306, user=‘root‘, passwd=‘abc456‘, db=‘paperdata‘,
charset=‘utf8‘)
self.cursor = self.db.cursor()
self.html_list = []
def getHtmlList(self):
response = requests.get(self.url, headers=self.header)
html_body = etree.HTML(response.text)
title = html_body.xpath("//dt[@class=‘ptitle‘]/a/@href")
for item in title:
self.html_list.append("http://openaccess.thecvf.com/" + item)
def getContent(self, url):
try:
response = requests.get(url, headers=self.header)
body = etree.HTML(response.text)
title = body.xpath("//div[@id=‘papertitle‘]/text()")[0]
abstract = body.xpath("//div[@id=‘abstract‘]/text()")[0]
down_url = body.xpath("//div[@id=‘content‘]//a/@href")[0].replace("../../", "http://openaccess.thecvf.com/")
sql = ‘‘‘insert into data values({},"{}","{}","{}")‘‘‘.format(0, title, down_url, str(abstract))
self.cursor.execute(sql)
print(title + "插入成功!")
self.db.commit()
except Exception as e:
print(e)
def run(self):
self.getHtmlList()
for url in self.html_list:
self.getContent(url)
if __name__ == ‘__main__‘:
spwder = Spider()
spwder.run()
我们来分析一下这个爬虫模块是如何运行的:首先是新建了一个类,在__init__初始化函数中定义了基本的爬取地址等变量。在getHtmlList方法中提取出了每个论文的详情链接,供在下面循环遍历使用。在
getContent方法中执行了一次插入方法。这里实际上只启动了一个事务。最后在run方法中循环执行插入方法。这个程序的好处在于,对每一个功能做了模块化的封装,提高了运行效率。但python里的插入还是有点慢,加上这是外网,所以爬取过程会耗费一定时间。网页分析就不再赘述,可以自行看代码分析。这里主要使用了xpath进行读取。
web端设计和分析
在搜查了资料后得知,echarts具有词汇云的拓展模块。于是上网搜索了一番后获得了相应的js文件,这东西官网有的下,不再提供下载地址了。对于echarts的用法,近一段时间已经十分熟悉了。这里主要说说service层的处理和点击事件的处理。由于我们从数据库读取的题目中并没有关键字,我们可以在service层对内容进行分析并统计出关键字次数。首先将每个题目都分成一个个单词,然后对单词出现次数做分析,筛选掉无用的介词如for in with等,如下代码:
public class DataService {
public List<Word> getData() throws SQLException {
DataDao dao = new DataDao();
List<Data> dataList= dao.getData();
List<Word> wordList = new ArrayList<Word>();
String [] names = new String[100000];
for(Data data:dataList) {
String name = data.getPapername();
String[] namestemp = name.split(" ");
names = (String[]) ArrayUtils.addAll(namestemp, names);//把两个字符数组合并。
}
HashMap<String, Integer> name_value = new HashMap<>();
//如果键出现过就+1,没有就记为1
for(String name:names) {
name_value.put(name, !name_value.containsKey(name)?1:name_value.get(name)+1);
}
//keySet()表示全部键
for(String name:name_value.keySet()) {
Word word = new Word();
if(name!=null&&(name_value.get(name)>1)&&(name.length()>4)) {
word.setName(name);
word.setValue(name_value.get(name));
wordList.add(word);
}
}
return wordList;
}
至于点击事件,首先在前台输入以下代码:
chart.on(‘click‘, function(params) {
var url = "clickFunction?name=" + params.name;
window.location.href = url;
然后就编写servlet等一系列层进行标题的模糊查询,返回集合后在前台读取即可。常规操作了,不再赘述。
总结
本次课堂作业的难度主要体现在爬取。一是外网,二是数据量庞大。加上python插入速度很慢,只能不断优化代码。也提醒我任何关于数据库的操作一定要捕获异常,以免程序会莫名其妙的中断。
原文地址:https://www.cnblogs.com/wushenjiang/p/12706581.html