Python 爬取 热词并进行分类数据分析-[热词分类+目录生成+关系演示+报告生成]
Posted 初等变换不改变矩阵的秩
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python 爬取 热词并进行分类数据分析-[热词分类+目录生成+关系演示+报告生成]相关的知识,希望对你有一定的参考价值。
日期:2020.02.04
博客期:143
星期二
【本博客的代码如若要使用,请在下方评论区留言,之后再用(就是跟我说一声)】
所有相关跳转:
a.【简单准备】
b.【云图制作+数据导入】
c.【拓扑数据】
d.【数据修复】
e.【解释修复+热词引用】
f.【JSP演示+页面跳转】
g.【热词分类+目录生成】(本期博客)
h.【热词关系图+报告生成】
i . 【App制作】
j . 【安全性改造】
如下图,我已经解决的需求是标黄的部分,剩余需求就只有 热词分类、目录生成、热词关系图展示、数据报告导出 四部分了,这些需求是最紧要完成的,呼~撸起袖子加油干!
1、热词分类
老师说要参照各大平台的分类,我就直接按照博客园的分类来吧(我实在看不懂那些机器学习是怎么实现的,连入门的门槛都远远不及)!如下图,可以看到 博客园的新闻将新闻分成了如下几类:互联网类、IT业界类、软件开发类、开源类、电脑硬件类、游戏类、创业类、手机相关类、科学类、其他类。我就根据这几类将对应类新闻里爬出来的数据进行对应类的划分。(看来又要重新爬数据了啊)
开始爬之前事先说明一下,这次改动应该是最后一次改动了,另外我发现每一类新闻都有 100 页,这...相当于每一类都有,所以不保证有误差的存在,另外为了减少数据量,我打算将 “频数为15” 这一条件上升到 “频数为20”,不然怎么爬的完?我先预算一下,今天和明天一起写这个博客,另外明天的话,就再写一份总结性的博客,这个小目标就算完结吧!当然最后可能会加入微信小程序部分或者APP部分,到时候再说。
根据这10类新闻,我们总共要爬取些什么数据呢?
首先,通过带有 header 的 request 方式爬取 https://news.cnblogs.com/ 这一初始链接,要爬以上 10 类新闻的链接,再爬取类中封装链接的构造,并开启新的爬取,对应每一类数据给爬到的热词信息后面追加一个“热词类型”的标签,这需要我们改造 KeyWords 类,向 KeyWords 类中加入 kind 属性,改写 __toString() 成员函数。之后改造调用过 KeyWords 类的地方。(News不需要)
关于分类页面的构造方法:
首先是原新闻网址:https://news.cnblogs.com/
其次,以 “互联网” 为例:https://news.cnblogs.com/n/c1101
然后是第 100 页的地址:https://news.cnblogs.com/n/c1101?page=100
很容易的判断到是在原网址的基础上加入对应 互联网的 a 标签上的 href 链接,需要将数据加载到一起来组成爬取链接!
但是爬的过程中发现了问题,就是我爬不到对应的分类链接,既然这样,我只能人工地获取它们的链接了,就10条数据无所谓了,本来因为懒想让网页帮我做的,看来是博客园让我勤快的。哈哈哈!
对应链接:
互联网类:https://news.cnblogs.com/n/c1101
IT业界类:https://news.cnblogs.com/n/c1102
软件开发类:https://news.cnblogs.com/n/c1103
开源类:https://news.cnblogs.com/n/c1109
电脑硬件类:https://news.cnblogs.com/n/c1111
游戏类:https://news.cnblogs.com/n/c1110
创业类:https://news.cnblogs.com/n/c1112
手机相关类:https://news.cnblogs.com/n/c1113
科学类:https://news.cnblogs.com/n/c1114
其他类:https://news.cnblogs.com/n/c1199
在 Surapity 类 中建立字典,存储类型的名称和对应链接。
爬取时间较长,从下午4:51到现在第2天的1:44,过程曲折且难以简言明之。
途中遇到好几个网站会使爬虫程序终止,比如 其他类的 Apple Watch UI动效解析 ,呜哇~试一次,卡一次。程序员的痛苦莫过于此!!!
统计基础数据共计 17469 条 数据!文件大小约为 1.96 M !
现在开始制作数据表:(先修改 fileR.py)
1 import codecs 2 3 4 def makeSql(): 5 file_path = "../../testFile/frc/words_sql.txt" 6 f = codecs.open(file_path, "w+", \'utf-8\') 7 f.write("") 8 f.close() 9 10 fw = open("../../testFile/frc/word.txt", mode=\'r\', encoding=\'utf-8\') 11 tmp = fw.readlines() 12 13 num = tmp.__len__() 14 15 for i in range(0,num): 16 group = tmp[i].split("\\t") 17 group[0] = "\'" + group[0] + "\'" 18 group[3] = "\'" + group[3][0:group[3].__len__()-1] + "\'" 19 f = codecs.open(file_path, "a+", \'utf-8\') 20 f.write("Insert into words values ("+group[0]+","+group[1]+",\'"+group[2]+"\',"+group[3]+",\'"+group[4]+"\');"+"\\n") 21 f.close() 22 23 makeSql()
执行并按照之前的方法导入数据,这里博主因为使用电脑管家清理了一下C盘,然后 Navicat就崩掉了,真的崩了(建立不了查询了,这个之后有解决方法的话,我再写一期博客吧!)!所以,不搞虚的,直接用文本导入了!
建立 keywords 表(或视图)的方法同上上期的博客,那样获取每一个热词的数量!
1 CREATE TABLE keywords 2 AS 3 ( 4 SELECT 5 word AS word, 6 SUM(num) AS num 7 FROM 8 words 9 GROUP BY word 10 ORDER BY num 11 DESC 12 )
哈哈哈哈!热词频数过万了呢!希望我的电脑还能撑住,继续爬!(但是现在已经2点了,先定个2个小时的闹钟,拓扑数据让它自己爬着)
对于 WebConnector 类,我要着重说一下,我本次爬取将此代码注释掉了:
# 这句话处理以后,就将带有 “年”、“月”、“日” 字眼的语句以及之后的语句全部清除掉了,当时是旨在消除不必要的解释部分,但现在看来没必要!多多益善嘛! tpl = StrSpecialDealer.ut_date(tpl)
早上醒来发现大问题——电脑自己休眠了,唉~希望自己能够吃一堑长一智吧!
在电脑熬夜干爬虫的时候尽力将休眠关闭,在设置中如下:
拓扑数据也完成了,大约又历时 5 个小时,关键是在电脑爬虫时我还不能用电脑干其他的(尤其是截图软件,运行的话,爬虫程序一准给你崩停)
终于有完整数据了,现在我们开始数据处理!
根据不同分类将数据汇总和数据处理了(也就是说剩余没有Python的事情了),至此热词分类完毕。
2、热词目录生成
我们需要展示每一个分类的前10个数据,以此做成第一个页面。
可以制作新的视图,也可以直接写大长 Sql 语句,我比较懒,就按长语句来了
1 package com.servlet; 2 3 import java.io.IOException; 4 import java.sql.SQLException; 5 import java.util.List; 6 7 import javax.servlet.ServletException; 8 import javax.servlet.ServletOutputStream; 9 import javax.servlet.annotation.WebServlet; 10 import javax.servlet.http.HttpServlet; 11 import javax.servlet.http.HttpServletRequest; 12 import javax.servlet.http.HttpServletResponse; 13 14 import org.json.JSONArray; 15 import org.json.JSONObject; 16 17 import com.dblink.basic.utils.SqlUtils; 18 import com.dblink.basic.utils.sqlKind.MySql_s; 19 import com.dblink.basic.utils.user.UserInfo; 20 import com.dblink.bean.BeanGroup; 21 import com.dblink.sql.DBLink; 22 23 @SuppressWarnings("unused") 24 public class ServletForMoreInfo extends HttpServlet{ 25 /** 26 * 27 */ 28 private static final long serialVersionUID = 1L; 29 //----------------------------------------------------------------------// 30 public void doPost(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException 31 { 32 request.setCharacterEncoding("utf-8"); 33 response.setCharacterEncoding("utf-8"); 34 response.setContentType("application/json"); 35 response.setHeader("Cache-Control", "no-cache"); 36 response.setHeader("Pragma", "no-cache"); 37 38 String kind = request.getParameter("kind"); 39 40 JSONArray jsonArray = new JSONArray(); 41 42 JSONObject jsonObj = new JSONObject(); 43 44 45 DBLink dbLink = new DBLink(new SqlUtils(new MySql_s("rc"),new UserInfo("root","123456"))); 46 BeanGroup bg = null; 47 try { 48 bg = dbLink.getSelect("Select word As word , SUM(num) As num From ( Select * From words Where kind = \'"+kind+"\' ) Group By word Order By num DESC Limit 0,10 ").beans; 49 50 int leng = bg.size(); 51 52 jsonObj.put("Length",leng); 53 54 jsonArray.put(jsonObj); 55 56 for(int i=0;i<leng;++i) 57 { 58 JSONObject jsonObject = new JSONObject(); 59 jsonObject.put("word",bg.get(i).get(0)); 60 jsonObject.put("num",bg.get(i).get(1)); 61 jsonArray.put(jsonObject); 62 } 63 } catch (SQLException e) { 64 // Do Nothing ... 65 } 66 dbLink.free(); 67 68 ServletOutputStream os = response.getOutputStream(); 69 os.write(jsonArray.toString().getBytes()); 70 os.flush(); 71 os.close(); 72 } 73 //---------------------------------------------------------------------------------// 74 }
如果你建立了对应 10 个分类的视图,你可以添加 Servlet 如下:(否则将视图名称替换成建立视图的Select语句)
1 package com.servlet; 2 3 import java.io.IOException; 4 import java.sql.SQLException; 5 import java.util.List; 6 7 import javax.servlet.ServletException; 8 import javax.servlet.ServletOutputStream; 9 import javax.servlet.annotation.WebServlet; 10 import javax.servlet.http.HttpServlet; 11 import javax.servlet.http.HttpServletRequest; 12 import javax.servlet.http.HttpServletResponse; 13 14 import org.json.JSONArray; 15 import org.json.JSONObject; 16 17 import com.dblink.basic.utils.SqlUtils; 18 import com.dblink.basic.utils.sqlKind.MySql_s; 19 import com.dblink.basic.utils.user.UserInfo; 20 import com.dblink.bean.BeanGroup; 21 import com.dblink.sql.DBLink; 22 23 @SuppressWarnings("unused") 24 public class ServletForKindKeyWords extends HttpServlet{ 25 /** 26 * 27 */ 28 private static final long serialVersionUID = 1L; 29 //----------------------------------------------------------------------// 30 public void doPost(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException 31 { 32 request.setCharacterEncoding("utf-8"); 33 response.setCharacterEncoding("utf-8"); 34 response.setContentType("application/json"); 35 response.setHeader("Cache-Control", "no-cache"); 36 response.setHeader("Pragma", "no-cache"); 37 38 String table = request.getParameter("table"); 39 String sql_rest = request.getParameter("sql"); 40 41 JSONArray jsonArray = new JSONArray(); 42 43 JSONObject jsonObj = new JSONObject(); 44 45 46 DBLink dbLink = new DBLink(new SqlUtils(new MySql_s("rc"),new UserInfo("root","123456"))); 47 BeanGroup bg = null; 48 try { 49 bg = dbLink.getSelect("Select * From "+table+" "+sql_rest).beans; 50 51 int leng = bg.size(); 52 53 int maxSize = dbLink.getSelect("Select * From "+table+" ").beans.size(); 54 55 int page = maxSize%leng==0?(maxSize/30):(maxSize/30)+1; 56 57 jsonObj.put("Length",leng); 58 jsonObj.put("MaxSize",maxSize); 59 jsonObj.put("Page",page); 60 61 jsonArray.put(jsonObj); 62 63 for(int i=0;i<leng;++i) 64 { 65 JSONObject jsonObject = new JSONObject(); 66 jsonObject.put("word",bg.get(i).get(0)); 67 jsonObject.put("num",bg.get(i).get(1)); 68 jsonObject.put("exp",bg.get(i).get(2)); 69 jsonArray.put(jsonObject); 70 } 71 } catch (SQLException e) { 72 // Do Nothing ... 73 } 74 dbLink.free(); 75 76 ServletOutputStream os = response.getOutputStream(); 77 os.write(jsonArray.toString().getBytes()); 78 os.flush(); 79 os.close(); 80 } 81 //---------------------------------------------------------------------------------// 82 }
然后制作 js 部分:
先显示分类,然后利用套装形式进行数据载入:
如果点击 获取本类更多热词,就可以跳转至本类页面!
Like this:
附加新 js 代码:
1 function makePageToKind() 2 { 3 var Area = \'\'; 4 Area += \'<div class="row">\'; 5 Area += \' <div class="col-md-12">\'; 6 Area += \' <h2>热词目录</h2>\'; 7 Area += \' </div>\'; 8 Area += \'</div>\'; 9 Area += \'<hr />\'; 10 Area += \'<br>\'; 11 Area += \'<br>\'; 12 Area += \'<div id="MessageArea">\'; 13 Area += \'</div>\'; 14 document.getElementById("page-inner").innerHTML = Area; 15 madeAllKindP(); 16 } 17 function madeAllKindP() 18 { 19 var Area = \'\'; 20 Area += \'<div>\'; 21 Area += \' <ul>\'; 22 Area += \' <li>\'; 23 Area += \' <b>互联网类<b>\'; 24 Area += \' <div id="hlw"></div>\'; 25 Area += \' </li>\'; 26 Area += \' <li>\'; 27 Area += \' <b>IT业界类<b>\'; 28 Area += \' <div id="ityj"></div>\'; 29 Area += \' </li>\'; 30 Area += \' <li>\'; 31 Area += \' <b>软件开发类<b>\'; 32 Area += \' <div id="rjkf"></div>\'; 33 Area += \' </li>\'; 34 Area += \' <li>\'; 35 Area += \' <b>开源类<b>\'; 36 Area += \' <div id="ky"></div>\'; 37 Area += \' </li>\'; 38 Area += \' <li>\'; 39 Area += \' <b>电脑硬件类<b>\'; 40 Area += \' <div id="dnyj"></div>\'; 41 Area += \' </li>\'; 42 Area += \' <li>\'; 43 Area += \' <b>游戏类<b>\'; 44 Area += \' <div id="yx"></div>\'; 45 Area += \' </li>\'; 46 Area += \' <li>\'; 47 Area += \' <b>创业类<b>\'; 48 Area += \' <div id="cy"></div>\'; 49 Area += \' </li>\'; 50 Area += \' <li>\'; 51 Area += \' <b>手机相关类<b>\'; 52 Area += \' <div id="sjxg"></div>\'; 53 Area += \' </li>\'; 54 Area += \' <li>\'; 55 Area += \' <b>科学类<b>\'; 56 Area += \' <div id="kx"></div>\'; 57 Area += \' </li>\'; 58 Area += \' <li>\'; 59 Area += \' <b>其他类<b>\'; 60 Area += \' <div id="qt"></div>\'; 61 Area += \' </li>\'; 62 Area += \' </ul>\'; 63 Area += \'</div>\'; 64 document.getElementById("MessageArea").innerHTML = Area; 65 makeNextStepOfGroupK("互联网类"); 66 makeNextStepOfGroupK("IT业界类"); 67 makeNextStepOfGroupK("软件开发类"); 68 makeNextStepOfGroupK("开源类"); 69 makeNextStepOfGroupK("电脑硬件类"); 70 makeNextStepOfGroupK("游戏类"); 71 makeNextStepOfGroupK("创业类"); 72 makeNextStepOfGroupK("手机相关类"); 73 makeNextStepOfGroupK("科学类"); 74 makeNextStepOfGroupK("其他类"); 75 } 76 function getKindWordsByKindName(word) 77 { 78 var id_t = ""; 79 if(word=="互联网类") 80 id_t = "hlw"; 81 else if(word=="IT业界类") 82 id_t = "ityj"; 83 else if(word=="软件开发类") 84 id_t = "rjkf"; 85 else if(word=="开源类") 86 id_t = "ky"; 87 else if(word=="电脑硬件类") 88 id_t = "dnyj"; 89 else if(word=="游戏类") 90 id_t = "yx"; 91 else if(word=="创业类") 92 id_t = "cy"; 93 else if(word=="手机相关类") 94 id_t = "sjxg"; 95 else if(word=="科学类") 96 id_t = "kx"; 97 else if(word=="其他类") 98 id_t = "qt"; 99 return id_t; 100 } 101 function makeNextStepOfGroupK(word_t) 102 { 103 var xmlHttp = null; 104 try{ 105 xmlHttp = new XMLHttpRequest(); 106 } catch (e1) { 107 try { 108 xmlHttp = new ActiveXObject("Microsoft.XMLHTTP"); 109 } catch (e2) { 110 alert("Your browser does not support XMLHTTP!"); 111 return; 112 } 113 } 114 xmlHttp.onreadystatechange = function() { 115 if (xmlHttp.readyState == 4) { 116 if (xmlHttp.status == 200) 117 { 118 var Area = " "; 119 s = xmlHttp.responseText; 120 var InformationSet = eval(\'(\'+s+\')\'); 121 var leng = InformationSet[0].Length; 122 123 var kindness = InformationSet[0].KindNess; 124 125 for(var i=1;i<=leng;++i) 126 { 127 var word_s = InformationSet[i].word; 128 var num = InformationSet[i].num; 129 Area += " "; 130 Area += "<a href=\'#\' title=\'在本类型中引用次数:"+num+"\' onclick=\'toSomeWhere(\\""+word_s+"\\")\'>"+word_s+"</a>"; 131 Area += " "; 132 } 133 Area += " "; 134 Area += " "; 135 Area += "<a href=\'#\' onclick=\'makePageToOneKind(\\""+kindness+"\\")\'/>获取本类更多热词...</a>"; 136 Area += " "; 137 Area += " "; 138 139 var id_t = getKindWordsByKindName(kindness); 140 document.getElementById(id_t).innerHTML = Area; 141 } 142 } 143 }; 144 var url ="../com/servlet/ServletForMoreInfo"; 145 以上是关于Python 爬取 热词并进行分类数据分析-[热词分类+目录生成+关系演示+报告生成]的主要内容,如果未能解决你的问题,请参考以下文章Python 爬取 热词并进行分类数据分析-[简单准备] (2020年寒假小目标05)
08 信息化领域热词分类分析及解释 第二步 将爬取的数据使用jieba分词处理并清洗