)
3.能创建非常可靠的Html文档结构(比如:html标签包含head 和 body,在head只出现恰当的元素)
爬虫系统的爬取对象分别选择了凤凰网新闻、网易新闻、搜狐新闻,因为这些新闻都开放了点击数量查询,且这三大媒体无论是影响上,还是覆盖面上,都是非常巨大非常广泛的,非常适合作为爬取对象,爬取过程中也没有复杂的Ajax需要处理,而且这些新闻的访问数据都是每天更新的。
爬虫程序需要以循环定时运行在响应的服务器上,每天定时爬取以上网站的新闻内容,并存入数据库,数据库采用了Mysql,因为Mysql比较轻量级,有免费的学术研究的版本,而且比较适合当前场景。Mysql数据库引擎采用了MyIASM,按理来说,MyIASM是比较古老的引擎,但是MyIASM存储引擎在曲度方面的性能要好于INNODB,虽然不支持事务,但是爬虫存储暂时不涉及事务的使用,再加上MyIASM优秀的插入查询速度,使得爬虫数据的存取非常快捷、迅速,所以这里选择了MyIASM作为Mysql的存储引擎。
数据采集系统的爬虫在爬取网站是采用多线程并发爬取的,所以多线程的爬虫对数据库的并发操作会有很多很多,在进行数据库操作的时候,第一步是建立数据库连接,在多线程的环境下,这些操作会进行得非常频繁,但是这些操作又非常的耗费网络、内存空间等,这些操作会对系统资源、系统运行效率有很大的负面影响,所以必须采用数据库连接池。网上有很多开源而且优秀的数据库连接池,比如Apache开源的dbcp,平时tomcat使用DateSource配置连接池的时候就是使用了tomcat内置的dbcp连接池,此外还有c3p0数据库连接池,也是非常优秀的连接池,SSH三大框架之一的Hibernate就采用了c3p0作为其内置连接池,其优秀性能可见一斑,不过这些连接池相对来说都比较重量级,所以自己在这里写了一个相对比较轻量级的连接池MF_DBCP,下面会介绍下自定义连接池相关内容。
省略
监视器初始化后开启两个线程: 1.号线程根据配置文件中的 status_checktime 字段来周期性运行实现扫描连接池中的坏链接并修复 2.号线程根据配置文件中的 num_checktime 字段来周期行创建连接池使用状态的快照,当足够三个状态时,根据三点画出的曲线来确定数据库连接池中到底需要保存多少连接,并保证连接数不小于最小连接数。 以下用 + 表示当前快照连接数大于前一快照,–表示当前快照连接数小于前一快照: +++ 监视器不做任何动作,因为连接数在稳步增加; -± 监视器末尾保留最后两个连接快照的平均连接数,剩下的多余连接回收; — 监视器保留三个快照平均连接数作为当前连接,剩下的多余连接回收; 自定义数据库连接池的相关API如下: addNew() 方法为连接池增加新的连接; addLast() 方法为未开启事务从而可以共享的连接提供”负载均衡”的策略(当一个连接被使用一次,则将他放入队列末尾,试想这样可以循环队列); deleteFirst() 方法循环调用可以清空连接池队列; delete() 方法提供了从连接池中移除某个连接的方法; getFirst() 方法提供了获取负载最轻即队首的连接; getLoad() 方法提供了获取指定连接负载大小的方法; getConnectionContainer() 方法提供了获取某个连接所在的连接容器(从而操作连接池中的连接池容器队列); remove() 方法提供了从连接池中移除某个开启了事务的连接,deleteLater() 方法提供了获取数据库中可以清除(负载等于0)的连接; getMinLoadConnection() 方法提供了获取连接池中负载最低的连接以便创造专用的事务连接; getConnectionContainers() 方法为外界提供了获取数据库连接池队列的方法; isFullFree() 方法判断当前连接池是否完全处于空闲状态(关闭连接池判断); size() 方法提供获取连接池除去事务连接剩余连接的数量; createConnection() 方法为连接池提供创造新连接的方法; destoryConnection() 方法指定关闭某个连接; repairPool() 方法提供了修复连接池中坏连接的方法,并用新的可用的连接替换; releasePool() 方法提供了连接池收缩大小的方法,确保保留的连接数是最合适的; revokeConnection() 方法提供了回收连接,将其重新加入连接池队列的方法; getConnection() 当用户需要连接时调用; getPoolStatus() 返回当前连接池的使用情况; close() 关闭数据库连接池;
4.1.2 中文分词模块 首先简单地介绍下中文分词的概念,中文分词也就是经过相关的算法,把原来的汉语句子或者更长的汉语语料正确分割成为一个一个的汉语词语的过程。
说到中文分词,先来介绍下英文的分词,计算机由欧美人发明,所以他们很早就进行了有关英文分词的研究,本文从简到繁进行介绍,英文分词很简单,人们平时阅读到的英文文章,英文单词与单词之间都有一个空格,利用这个特点,程序可以非常迅速的将英文文章进行英文分词。这时候回过头来看看汉语,发现问题来了,除了语句中的标点符号,基本上所有的汉语都是连续的,并没有非常明显的分割的特征。这时候原来用于英文分词的那一套工具在汉语语料的分词方面完全没有一点作用了,当然,也不能要求在汉语写作中学习英文的方式,在词语与词语之间用空格作为间隔,所以需要专门研究下汉语的分词策略。
这时候,再回到英文分词的思路上,从小到大,可没少学过英语短语,是不是发现了什么?英文短语与短语之间的分词也不能单纯的用空格作为判断了。但是英文单词之间的组合以及规律要明显比汉语强很多很多,但是汉语拥有世界上最大的使用群体,研究汉语中文分词技术还是非常非常有必要的。到底怎么进行汉语中文分词呢?所以首先得研究研究汉语的语法。
在这里声明下,汉语中文分词目前并不涉及到汉语古文的分词,具体的原因是因为古文的分词难度泰国巨大,基本上无规律可言。
经过这些年大量计算机爱好者和学术工作者的研究探索,逐渐推出了一些半成熟的中文分词的算法,中文分词的路上举步维艰,还需要各位加油研究。在这里本文先介绍下几种比较常见中文分词的算法: (1)字符匹配的中文分词方法 字符匹配的中文分词方法时基于语料词典的分词算法,分词结果的准确性很是依赖是否有一个好的分词词典,算法的具体内容是,首先将分词词典以某种数据结构的形式载入内存,一般都是Hash散列存储的方式,因为这个方式有极快的查找速度,然后根据分词词典中的词语去匹配要分词的中文语料字符串,经过一些比较细腻的匹配规则,最终能够成功将该汉语语料字符串拆分成不重复的若干汉语词语,即匹配完成。
再拆分要分词的汉语语料时候,应该结合多种多样的拆分方法,因为不同的拆分方法可能会带来完全不同的分词结果。面对一个随机的符合规范的汉语语料,如果它具有足够的长度,足够清晰而且不存在理解歧义的情况下,从不同的拆分方法出发,最终得到的分词结果一定是一致的。
利用计算机分词的话,必定存在着很多奇奇怪怪的分词结果,完全可以采用统计学的方法来提高最终的分词结果集的正确命中率。具体的做法是,定制多个拆分汉语语料的算法,然后分别计算其最终的分词结果,然后统计最终的结果集,哪一部分分词结果在最终分词的结果集中出现的次数最多,则就取该分词作为最终的分词结果。
本文最终采用的分词方法即为本分词方法的改进版本,结合了IK分词和Lucene的一些特性。字符匹配的中文分词算法对一个合适的分词词典依赖非常大,那么如何得到这个分词词典呢?最笨的办法就是人工审阅新闻资料,或者下载汉语字典,提取其中的词语作为分词词典,其次,分词词典还需要进行不断进化。层出不穷的网络新词,对分词结果造成了巨大的挑战,这里就不讨论程序自学习以及词典的自动扩展算法了。常用的中文分词算法有下面几种:
(2)语义分析理解的中文分词方法 这种中文语料的分词方法时首先要分析得出汉语的语义、语法、句法等,得出这些规律目标是能利用这些规律来让计算机能理解汉语语句的意义,但是这种方法看似完美,但是有很遥远。首先想要彻底能总结出这些规律本身就是非常复杂的,因为汉语整个语法体系的复杂性,还有就是汉语的灵活组合性,不同的组合就是不同的意思,例如“我还欠了他的钱”,这句话如果把“还”念作“hai”,整个句子的意思是“我现在还欠着他的钱”,但如果把“还”念作“huai”,那整个句子的意思就变成“我还钱了,把欠他的钱都还给他了”,这种情况识别就一定会出现问题。再者就是如果得出了这些规律,也要把这些规律以编程的方式实现出来,这个过程也是非常困难的。语义分析理解的中文分词方法是跟人工智能的发展息息相关的,如果能实现基于语义分析的中文语料的分词,那么人工智能也能获得长足的发展。 因为本算法的研制工程周期长,且困难,目前在国际上都还处于概念阶段。就算实现了对汉语的语义语法理解,世界上还有其他语言:英语、俄语、法语、阿拉伯语等等语言,发展历程必然艰难。本文在此提及此方法仅作为一种思路,目前没有实现的思路。
(3)统计的中文分词方法 如果从汉语词语的角度出发去研究词语的规律,很快就可以得到一个结论,那就是相互组成一个词语的两个汉字顺序出现在一起的频率会很高。可以利用这个特点来判定任意相邻的汉字是否组成了一个词,但是很明显存在一个问题,到底多高的频率才能证明这几个字组成了一个词?从数学的角度来看,这不是单一系数就能解决的问题,也绝对不是单一的函数关系,因为变量太多了,可能不同的汉字本身达到可以判定它跟某个汉字组合成词的阈值是不同的,比如一些生僻的字,本文在这块献丑举个例子:“好”这个字,它可以组成“好人”,“美好”,“刚好”,“恰好”,“好运”,“好奇”,“合好”,“友好”,“问好”,“讨好”……等等词语,在百度上搜到的结果有7500条之多;举另外一个字“驭”,用“驭”组词,有“驾驭”,“驭风”……等词语,仅仅只有120条左右,明显“好”跟“驭”两个字不能用一样的判定标准,它们出现的频率差异太大,是不能共用一套判定方案来判断它们是否组字成词的。
其次,还有一个问题,有一些特殊的汉字,他们也会对整个中文分词结果产生不可忽视的干扰作用,例如“了”,“的”,“着”,这些词语各自可以组字成词,例如“了解”,“目的”,“着手”等等,但是他们在整个中文语料中更多的形式是类似于这样的形式:“走了”,“累了”,“掉了”,“好的”,“你的”,“他的”,“走着”,“跑着”,“着了”等等形式,这样的形式明显不是词语,这些字经常作为结束语出现,可能对整个基于词频的汉语分词算法产生巨大的干扰作用,而在中文语料中,列举出来的这几个词还仅仅是冰山一角。所以这种方法仅仅单靠词频是完全不够的。 不过,到目前,人工智能越来越热,发展也变得迅速起来,不得不说这种方法是具有一定的前瞻性的,如果事先能给出大量的汉语语料的训练集,再辅以人工纠错与修正操作,是这种统计的中文分词算法越来越准确,相信这种方法在不久的未来会替代其他的分词算法。在处理自然语言上,去理解语义、语法这才是正道。通过建立相关的语法模型,不断地进行统计分词的训练,后期算法一定会有非常不错的分词成果,不过本文研究仅仅是借用中文分词的工具,也不会在这方面进行太过深入的讨论。顺便提下,作为训练集的语料完全可以采用类似本文的爬虫系统从网络上每天搜集到最新的新闻情报进行训练,人工纠错,因为没有比新闻更有实效性的汉语语料训练集了,这样“网络新词”也能得到及时的补充与学习,后期需要人工参与纠正的次数会越来越少,分词结果也会越来越准确。
本文使用了IK Analyzer作为汉语分词的工具。IK Analyzer是一个完全免费开源的中文分词的工具,基于Java开发的非常优秀、快速的中文分词的工具包。国内还有一个较为著名的中文分词工具Ansj,号称能很好的识别人名与地名,而且处理速度方面完全超越IK分词,不过由于IK分词基于Lucene,最近自己又在研究Lucene的原因,况且对IK的分词结果也还算满意。
本系统使用的IK Analyzer的版本为2012u6,作者林良益是一名自身的Java程序开发工程师。在IK Analyzer中能看到很多Lucene的影子,比如IK分词的核心就是基于Lucene的,其中大量的导包也能看出来源于Apache Lucene。现在有空也在研究IK分词的算法以及原理,希望能给许久未更新的IK分词加入自己的贡献,IK分词系统结构图如图4-1所示。
图4-1 IK分词的设计结构图 4.1.3 相似度匹配模块 利用中文分词工具将爬虫系统采集回来的数据进行中文分词之后,则需要分析文章的相似度,之后再将相似的文章的数据整合到一起,为之后可视化展示同一条新闻的变化趋势打下基础,其中计算文章相似度的算法有很多,主要来说是有两种,一种是余弦定理,另一种是计算杰卡德距离的方法。
1.余弦定理相似度计算法 余弦定理是怎么能应用到计算文章的相似度呢?先想想余弦定理的概念,如果能将两篇文章转换为数学中的两条向量,那么可以用过余弦定理来计算这两条向量之间的夹角。具体应该怎么能将文章转换为数学中的向量呢?这里就用到了中文分词,然后可以将带分析的汉语语料进行中文分词,并保存各自的分词结果集A,B。分词结束后再另外设置一个集合S,令S = A ∪ B,那么分别计算A,B两个集合中的词语在原始预料中的词频,然后建立A、B到S的映射,如果S中有而A或者B中没有,那么记该词语的词频为0,那么就能得到两条维度相同的向量,这样就可以用余弦定理来计算相似度了。 第一步,进行中文语料的分词。 句子A:我/喜欢/看/电视,不/喜欢/看/电影。 句子B:我/不/喜欢/看/电视,也/不/喜欢/看/电影。 第二步,列出所有汉语词语的集合。 我,喜欢,看,电视,电影,不,也。 第三步,计算集合中每个词语的词频。 句子A:我 1,喜欢 2,看 2,电视 1,电影 1,不 1,也 0。 句子B:我 1,喜欢 2,看 2,电视 1,电影 1,不 2,也 1。 第四步,写出每句话的词频向量。 句子A:[1, 2, 2, 1, 1, 1, 0]。 句子B:[1, 2, 2, 1, 1, 2, 1]。 有了词频向量,中文文章的相似度计算问题就简化了,变成了如何去计算这两个词频向量的离合程度。首先可以把这两条词频向量想象成存在于空间中的两条任意线段,这两条线段必然能组成类似于下图的夹角,再计算夹角的余弦值。 在这里讨论下最简单的维度,也就是二维空间,下图的a和b是两个字母分别代表两个不同的向量,需要计算它们夹角的余弦值COSθ,如图4-2所示。
图4-2 两向量形成夹角
向量a,b所构成的夹角如图4-3所示。
图4-3 向量a,b所构成的夹角 可以采用下列公式来计算出夹角θ的余弦值,计算公式如图4-4所示。
图4-4计算ab两向量的余弦值公式 如果是多维向量呢?如何计算多维向量在空间中的夹角的余弦值?经由数学推导,可以使用下面多维向量的余弦值计算公式如图4-5所示。
图4-5 多维向量的余弦值计算公式 两个汉语词组的词频向量的余弦值可以作为这两篇汉语语料整体相似度的度量,因为从数学上来讲,当两向量的余弦值越接近或完全等于0,则表明两个向量的夹角是两条方向完全垂直的,在中文语法的角度来解释向量垂直,就是两篇语料的分词结果是完全没有一样的,这样有很大的可信度表明,这两篇文章内容是完全不相干的,反过来,如果俩向量的夹角的余弦接近或完全等于1,则表明这两条向量几乎可以看做成同一条向量,从中文语法的角度来解释,也就是两篇中文语料的分词结果基本上是一致的,有很大的可信度表明,这两篇文章的内容是完全类似的。
由此,就得到了“找出相似文章”的一种算法: (1)使用中文分词算法,首先需要找出这两篇带分析文章的重要关键词。 (2)从每篇文章分别取出所有的关键词,将其合并成为一个集合,然后来计算这两篇文章相对于关键词集合的词频,这样就生成了这两篇文章两条待分析的词频向量。 (3)最后计算这两个词频向量的余弦值,余弦值越接近于1则文章越相似。 “余弦相似度”是一种非常有用的算法,凡事想要知道任意两个向量的相似程度,都可以使用余弦定理。
4.1.4 数据展示模块 经过相似度匹配算法匹配为相似文章的算法则存储到同一条数据记录之中存入数据库,然后将相似数据读取出来,将数据以可视化的形式展示出来,步骤如下: (1)将POJO对象转换为JSON: JSON(JavaScript Object Notation) 是一种非常轻量级的类似而又超越可扩展标记语言的数据交换的格式。JSON是基于ECMAScript的一个子集。 JSON采用了完全独立于任何编程语言的书写格式,但也使用了非常类似C语言家族的一些语法习惯(包括C、C++、C#、Java、JavaScript、Perl、Python等)。
JSON一经推出,直到现在,在数据交换载体的选择上完全有替代XML的趋势。最近在公司写的一个金融项目,是为财新网写的债券实时行情的金融项目,项目中后台数据传送到前台用的是Servlet,Servlet中是将从Service层中得到的数据对象(一般都是List、Map、或者其他的POJO对象),经过fastjson转换成为JSON字符串,最终输出在Servlet上。然后前台js用ajax异步加载的方式调用Servlet,可以很容易的将获取到的JSON字符串转化为相关的对象。
此外,有大量的测试表明,同样字节数同样大小的JSON可以装载的数据信息量要比XML多出很多,这样就表明,JSON的压缩性更好,自身的负载效率高,所以,如今越来越多的网站数据交互、以及企业级的信息交互、经典的C-S模式都逐渐改用了JSON作为数据传递的载体。
从JavaScript语言层来看,JSON俨然就是JavaScript中的数组类型与对象类型之间的组合体,有点类似与C语言中结构体strut的语法定义模式,很明显,strut能通过对不同数据结构的组合,再添加各种各样的数据嵌套,可以表示世界上任意一种信息格式,JSON非常类似于这种结构体,正因为JSON作为一种高效的数据载体来说可谓是“无所不能”,近些年,有关JSON的发展飞速而且迅猛。下面分别简单介绍下JavaScript中的对象与数组:
对象: JSON对象在js中表示为用“{}”括起来的内容,其数据结构为 {key:value,key:value,…}的键值对的结构,在绝大多数的面向对象的编程语言中,key即键是对象属性的名字,而value即值则是对象的属性值。在C语言、Java、Python等语言中通过Object.key来取得value的具体的值。
数组: 数组在js中是中用括号“[]”符号包含起来的内容,js数组的数据结构如 [“this”,“a”,“test”,…],使用数组的索引可以来获取数据相应位置的数值,数值的数据类型包括各种各样的数据类型:对象、字符串、数字、数组等等。实验证明经过对象、数组2种数据结构是可以组合成各种各样任意复杂度的数据结构。
现如今,可以把POJO对象转换为JSON的工具有很多,比如谷歌的Gson工具包,比如阿里贡献的开源JSON转换工具fastjson,本文使用了阿里巴巴的fastjson。Fastjson提供了包括JSON数据的“序列化”和“反序列化”两部分的JSON相关的功能,其优势有:号称对JSON数据的解析与反解析速度最快,测试表明,fastjson具有极快的性能,超越任其他的Java Json parser,包括自称最快的JackJson。FastJson功能强大,完全支持Date、Enum、Java Bean、Set、Map、等常见的数据模式与类型,并且原生,能在所有Java能运行的地方运行。Java对象转换为JSON格式,一般有以下几种情况: Java普通单节点对象转换为JSON的原理: 通过对象的get()方法来获取对象的属性的值即JSON数据的值,然后通过get()方法的函数名得出具体是get的哪个成员变量,于是这样就能得出了JSON数据的键,然后经过复合JSON语法的拼接与组合,就成功将对象转换为了JSON。但如果对象没有提供响应的get()方法呢?那么就需要通过Java的反射机制来拿出要转换成JSON的对象的字段,然后判定哪些字段是必须的,同时抛弃掉“垃圾数据”的字段,最终将字段组合成JSON。组合成JSON的时候,其字段名称作为String类型的key存在,其属性值作为相对应数据类型的key存在,如图4-6所示。
图4-6 对象转换为JSON原理图 Java普通单节点数组转换为JSON的原理: Java普通单节点数组转换为JSON可以由单节点转换JSON拓展而来,如图4-7所示。
图4-7 对象数组转换为JSON原理 Java复合对象转换为JSON的原理: Java符合对象转换为JSON其实就是Java普通单节点对象转换为JSON的原理的拓展,获取了字段名字之后,获取字段对应的属性的时候,需要判定该属性具体的数据类型,如果该属性的具体数据类型是基本数据类型中的一种,就必须使用该数据类型对应的JSON表示方法表示出来(例如有没有引号之分就是区别字符串变量与其他变量之间的区别的),如图4-8所示。
图4-8 复合对象转换为JSON原理 (2)将Json数据以可视化的形式展示出来 显示相似新闻数据使用了开放的图表绘制类库JfreeChart,JfreeChart工具使用纯Java语言编写而来,完全是为applications, applets, servlets 以及JSP等的使用而设计。JFreeChart可以生成例如散点图(scatter plots)、柱状图(bar charts)、饼图(pie charts)、甘特图(Gantt charts)、时序图(time series)等等多种图表,此外还可以生成PNG和JPEG格式进行输出,也可以和PDF和EXCEL等工具关联。
到目前为止,在Java中JFreeChart是非常不错的统计图形解决方案,JFreeChart基本上能够满足目前的Java在统计绘图方面的各种需求。 JFreeChart的优秀特性包括以下几点: 一致的和清晰明确的API,而且支持多种图表类型。 设计非常灵活,对各种应用程序来说非常容易扩展。 支持多种多样的输出类型,包括Swing组件、图像文件(PNG、JPEG)、矢量图形文件(PDF、EPS、SVG)。 JFreeChart是完全“开源”的,或者更具体地说, 自由软件。它是遵循GNU协议的。 JfreeChart优点如下: 稳定、轻量级且功能非常强大。 免费开源,但是开发手册和示例要花钱购买。 其API学习起来非常简单,整个工具容易上手。 生成的图表运行非常地顺畅。
4.2 系统异常处理 系统在运行过程中因为复杂的运行环境,可能会产生种种异常问题。 4.2.1 爬虫异常总体概况 省略
4.2.2 爬虫访问网页被拒绝 爬虫大量爬取网站时,会对网站资源占用严重,所以很多网站加入了反爬虫机制,大量爬取网站数据时,会出现Access Denied一类的错误,网页服务器直接拒绝了访问,这时候爬虫就得需要能伪装的像一个真正的浏览器一样,有如下方法: (1)伪装User-Agent User-Agent标明了浏览器的类型,以便Web网站服务器能识别不同类型的浏览器。为什么要识别不同类型的浏览器呢?现在主流的优秀浏览器有windows10的Edge浏览器、微软的IE系列浏览器、谷歌的Chrome浏览器、Mozilla的FireFox浏览器,还有来自挪威的Opera浏览器,这些浏览器五花八门,分别出自各自的厂家,所以面对同样的html元素,他们的解析效果有可能是非常不同的,甚至会出现无法解析一些Html元素的情况,正式因为如此,所以Web网站服务器要判断不同的浏览器以便提供不同支持方案(例如CSS中针对不同的浏览器可能需要不同的标注)。
所以现在绝大部分的爬虫为了能够及时获取网站的数据,通常会设置一个某种浏览器的User-Agent以此来“欺骗”网站,告诉Web网站服务器自己是某一种浏览器,然后网站Web服务器才会返回真实的网页数据,一般比较常见几个浏览器的User-Agent如下: Chrome的User-Agent:Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36 火狐的User-Agent:Mozilla/5.0 (Windows NT 6.3; WOW64; rv:44.0) Gecko/20100101 Firefox/44.0 IE的User-Agent:Mozilla/5.0 (Windows NT 6.3; WOW64; Trident/7.0; .NET4.0E; .NET4.0C; .NET CLR 3.5.30729; .NET CLR 2.0.50727; .NET CLR 3.0.30729; rv:11.0) like Gecko
HttpClient设置User Agent的方法如下: HttpGet getMethod = new HttpGet(“URL”); getMethod.setHeader(“User-Agent”, “user agent内容”);
(2)需要登录后才能访问网页数据 虽然绝大部分网站不登陆就能访问各个页面的内容,随着各个研究机构对互联网数据的需求越来越多的情况下,各种各样的爬虫随之诞生,但是一部分爬虫会无节制的爬取网站,大大地消耗了网站的带宽,导致正常的用户都无法访问网站,所以现在的绝大部分网站都相应推出了一些防护“恶意爬虫”的策略,例如网站一旦检测到某个IP的访问量有异常,就会要求这个IP访问的时候必须登录后才能访问。不过这样也有解决方法,可以直接在该IP所在主机上用浏览器登录,登录成功之后,如果浏览器是Chrome或者firefox那么可以直接查看浏览器的cookie,用HttpClient设置cookie即可访问即可。不过还有一些检测机制特别严格的网站,登录网站的时候必须填写随机验证码,这类网站的爬取难度可就大了,需要能识别网站随机扭曲的验证码,这些问题在本文不做讨论。
(3)使用代理IP访问 如果网站服务器维护人员用某段时间内某IP的访问次数来判定爬虫,然后将这些爬虫的IP都封掉的话,以上伪装就失效了。为了解决爬虫的IP被相关网站封停,仔细一想,如果爬虫能模拟出一批用户来访问该网站不就能解决这个问题吗?具体应该如何模拟呢?首先需要模拟出一个一个分散而又独立的用户,这就需要随机而又分散到全国各地的IP代理,爬虫运行的时候从这些IP代理中随机选取一部分IP作为代理使用,这样就能比较完美地解决单IP高频率高流量访问网站的问题了。
拥有了这些IP代理之后,应该如何去管理这些代理IP呢?这里可以做一个类似于数据库连接池的东西,当然这里存放的不是数据库连接,而是一个一个的代理IP,然后指定相关的代理IP分配策略。代理IP池做好之后,要做一个负载均衡,每次轮流使用代理IP池中可以正常使用的IP做循环访问,这样单一IP对网页服务器会迅速下降,非常明显。
5 软件测试 省略
5.1 白盒测试 白盒测试是一种基于软件逻辑结构设计的测试,在整个测试过程中,测试的参与者是完全熟知整个系统的逻辑分支的。白盒测试的盒子是指被测试的软件系统,白盒指的是程序结构与逻辑代码是已知的,非常清楚盒子内部的逻辑结构以及运行逻辑的。“白盒”法全面了解程序内部逻辑结构、对所有逻辑路径都进行相关测试。“白盒测试”会争取能够测试完软件系统中所有的可能的逻辑路径。使用白盒测试的方式时,一定要先画出软件所有的逻辑顺序结构与设计,然后再分别设计出合适而又全面的测试用例,最终完成白盒测试。 5.1.1 爬虫系统测试结果 因为爬虫系统逻辑设计相对来说是比较简单的,不涉及到基本路径法,因为整个正序只需要定时运行就行,不像其他软件系统那样,有较深的用户需求根基,需要相关人员配合使用。本次开发的爬虫系统是全自动的,所以百合测试结果与黑盒测试结果一致。 下图为爬虫系统的百合测试结果截图,测试方法即定时运行爬虫即可,下图中的条目为爬虫此次执行所爬取到结果中的一部分,爬取结果如图5-1所示。
图5-1 爬虫爬取结果 5.1.2 中文分词系统测试结果 中文分词系统测试也比较简单,没有复杂的业务逻辑,结果基本呈线程顺序,且执行路径唯一,下图为中文分词系统的白盒测试结果,首先是测试的语料的截图,如图5-2所示。
图5-2 中文分词原文 最终的分词结果如下,目前想要提高分词结果非常困难,需要加大词库的准确性,白盒测试结果如图5-3所示:
图5-3 中文分词结果 5.1.3 中文文章相似度匹配系统测试结果 中文文章相似度计算方法采用了余弦定理计算两篇文章所对应的汉语词语的词频向量的夹角的余弦值,在经过大量的试验后发现其准确率还是非常非常高的,测试结果如图5-4所示。
图5-4 余弦定理相似度匹配 可以看出,“国家专项计划引苏鄂家长担忧教育部回应”这篇新闻与“向中西部调剂生源致高考减招数万?湖北江苏连夜回应”两条新闻均是有关高考的,完美匹配到了一起,其次不排除有些极端的情况,导致匹配结果不正确,这个也会继续研究,提高准确率。
5.1.4 相似新闻趋势展示系统测试结果 相似新闻的展示采用了JfreeChart作为白盒测试的测试对象,测试结果如下图所示,精确显示了每一条新闻的关注度走势,如图5-5所示。
图5-5 JfreeChart测试图
5.2 黑盒测试 黑盒测试与白盒测试恰好相反,从名字就能看出,一黑一白,白盒测试者熟悉盒子中的内容,而黑盒测试者是完全不知道盒子中的内容的。黑盒测试主要是面向程序的功能实现而进行的测试,例如检验程序是否具有某一功能,而完全不必关心程序的逻辑设计。也就是说,整个黑盒测试关注的是软件系统的功能完整性,而不考虑程序逻辑上的BUG等问题。 5.2.1 爬虫系统测试结果 上面已经提到,本爬虫系统逻辑较为简单,白盒测试结果与黑盒测试结果一致,结果如图5-6所示。
图5-6 爬虫系统黑盒测试
5.2.2 中文文章相似度匹配系统测试结果 总体来说,黑盒测试的结果也是比较令人满意的,同样,瑕疵还是有的,这也是编程的挑战与乐趣所在之处,黑盒测试结果如图5-7所示。
图5-7 中文匹配黑盒测试 5.2.3 相似新闻趋势展示系统测试结果 黑盒测试相似新闻趋势展示系统测试了Echarts的效果,以便能跟白盒测试JfreeChart区别开来,测试结果如图5-8所示。
图5-8 黑盒测试新闻排行 点击上面的相关新闻会出现单个新闻的趋势发展图,如图5-9所示。
图5-9 echarts黑盒测试
6 结 论 省略
参考文献 [11] 于娟,刘强. 主题网络爬虫研究综述[J]. 计算机工程与科学, 2015, 37(02):231-237. [12] 张红云. 基于页面分析的主题网络爬虫的研究[D]. 武汉理工大学, 2010. [13] 张莹. 面向动态页面的网络爬虫系统的设计与实现[D]. 南开大学, 2012. [14] 张晓雷. 面向Web挖掘的主题网络爬虫的研究与实现[D]. 西安电子科技大学, 2012. [15] 奉国和,郑伟. 国内中文自动分词技术研究综述[J]. 图书情报工作, 2011, 55(2):41-45. [16] 许智宏,张月梅,王一. 一种改进的中文分词在主题搜索中的应用[J]. 郑州大学学报, 2014(5):44-48. [17] 欧振猛,余顺争. 中文分词算法在搜索引擎应用中的研究[J]. 计算机工程与应用, 2000, 36(08):80-82. [18] Batsakis.S, Petrakis E G M, Milios E. Improving the performance of focused web crawlers[J]. Data & knowledge engineering, 2009, 68(10):1001-1013. [19] Pant.G, Menczer F. MySpiders:Evolve Your Own Intelligent Web Crawlers[J]. Autonomous agents and multi-agent systems, 2002, 5(2):221-229. [20] Ahmadi-Abkenari F, Ali S. A Clickstream-based Focused Trend Parallel Web Crawler[J]. International Journal of Computer Applications, 2010, 9(5):24-28.
致 谢 省略
外文资料 省略
中文翻译 省略
5、资源下载
本项目源码及完整论文如下,有需要的朋友可以点击进行下载。如果链接失效可点击下方卡片扫码自助下载。
序号
毕业设计全套资源(点击下载)
本项目源码
基于java+Jsoup+HttpClient的网络爬虫技术的网络新闻分析系统设计与实现(源码+文档)网络爬虫_数据挖掘.zip
你可能感兴趣的:(精选毕业设计完整源码+论文,爬虫,java,python)
python 读excel每行替换_Python脚本操作Excel实现批量替换功能
weixin_39646695
python 读excel每行替换
Python脚本操作Excel实现批量替换功能大家好,给大家分享下如何使用Python脚本操作Excel实现批量替换。使用的工具Openpyxl,一个处理excel的python库,处理excel,其实针对的就是WorkBook,Sheet,Cell这三个最根本的元素~明确需求原始excel如下我们的目标是把下面excel工作表的sheet1表页A列的内容“替换我吧”批量替换为B列的“我用来替换的
移动端城市区县二级联动选择功能实现包
good2know
本文还有配套的精品资源,点击获取简介:本项目是一套为移动端设计的jQuery实现方案,用于简化用户在选择城市和区县时的流程。它包括所有必需文件:HTML、JavaScript、CSS及图片资源。通过动态更新下拉菜单选项,实现城市到区县的联动效果,支持数据异步加载。开发者可以轻松集成此功能到移动网站或应用,并可基于需求进行扩展和优化。1.jQuery移动端解决方案概述jQuery技术简介jQuery
SpringMVC执行流程(原理),通俗易懂
国服冰
SpringMVC spring mvc
SpringMVC执行流程(原理),通俗易懂一、图解SpringMVC流程二、进一步理解Springmvc的执行流程1、导入依赖2、建立展示的视图3、web.xml4、spring配置文件springmvc-servlet5、Controller6、tomcat配置7、访问的url8、视图页面一、图解SpringMVC流程图为SpringMVC的一个较完整的流程图,实线表示SpringMVC框架提
深入解析JVM工作原理:从字节码到机器指令的全过程
一、JVM概述Java虚拟机(JVM)是Java平台的核心组件,它实现了Java"一次编写,到处运行"的理念。JVM是一个抽象的计算机器,它有自己的指令集和运行时内存管理机制。JVM的主要职责:加载:读取.class文件并验证其正确性存储:管理内存分配和垃圾回收执行:解释或编译字节码为机器指令安全:提供沙箱环境限制恶意代码二、JVM架构详解JVM由三个主要子系统组成:1.类加载子系统类加载过程分为
Spring进阶 - SpringMVC实现原理之DispatcherServlet处理请求的过程
倾听铃的声
后端 spring java mvc 开发语言 分布式
前文我们有了IOC的源码基础以及SpringMVC的基础,我们便可以进一步深入理解SpringMVC主要实现原理,包含DispatcherServlet的初始化过程和DispatcherServlet处理请求的过程的源码解析。本文是第二篇:DispatcherServlet处理请求的过程的源码解析。@pdaiSpring进阶-SpringMVC实现原理之DispatcherServlet处理请求的
JVM 内存模型深度解析:原子性、可见性与有序性的实现
练习时长两年半的程序员小胡
JVM 深度剖析:从面试考点到生产实践 jvm java 内存模型
在了解了JVM的基础架构和类加载机制后,我们需要进一步探索Java程序在多线程环境下的内存交互规则。JVM内存模型(JavaMemoryModel,JMM)定义了线程和主内存之间的抽象关系,它通过规范共享变量的访问方式,解决了多线程并发时的数据一致性问题。本文将从内存模型的核心目标出发,详解原子性、可见性、有序性的实现机制,以及volatile、synchronized等关键字在其中的作用。一、J
互信息:理论框架、跨学科应用与前沿进展
大千AI助手
人工智能 Python # OTHER 人工智能 深度学习 算法 互信息 香农 通信 随机变量
1.起源与核心定义互信息(MutualInformation,MI)由克劳德·香农(ClaudeShannon)在1948年开创性论文《AMathematicalTheoryofCommunication》中首次提出,该论文奠定了现代信息论的基础。互信息用于量化两个随机变量之间的统计依赖关系,定义为:若已知一个随机变量的取值,能为另一个随机变量提供的信息量。数学上,对于离散随机变量XXX和YYY,
Java | 多线程经典问题 - 售票
Ada54
一、售票需求1)同一个票池2)多个窗口卖票,不能出售同一张票二、售票问题代码实现(线程与进程小总结,请戳:Java|线程和进程,创建线程)step1:定义SaleWindow类实现Runnable接口,覆盖run方法step2:实例化SaleWindow对象,创建Thread对象,将SaleWindow作为参数传给Thread类的构造函数,然后通过Thread.start()方法启动线程step3
SpringMVC的执行流程
1、什么是MVCMVC是一种设计模式。MVC的原理图如下所示M-Model模型(完成业务逻辑:有javaBean构成,service+dao+entity)V-View视图(做界面的展示jsp,html……)C-Controller控制器(接收请求—>调用模型—>根据结果派发页面2、SpringMVC是什么SpringMVC是一个MVC的开源框架,SpringMVC=Struts2+Spring,
JAVA接口机结构解析
秃狼
SpringBoot 八股文 Java java 学习
什么是接口机在Java项目中,接口机通常指用于与外部系统进行数据交互的中间层,负责处理请求和响应的转换、协议适配、数据格式转换等任务。接口机的结构我们的接口机的结构分为两个大部分,外部接口机和内部接口机,在业务的调度上也是通过mq来实现的,只要的目的就是为了解耦合和做差异化。在接口机中主要的方法就是定时任务,消息的发送和消费,其他平台调用接口机只能提供外部接口机的方法进行调用,外部接口机可以提供消
最新阿里四面面试真题46道:面试技巧+核心问题+面试心得
风平浪静如码
前言做技术的有一种资历,叫做通过了阿里的面试。这些阿里Java相关问题,都是之前通过不断优秀人才的铺垫总结的,先自己弄懂了再去阿里面试,不然就是去丢脸,被虐。希望对大家帮助,祝面试成功,有个更好的职业规划。一,阿里常见技术面1、微信红包怎么实现。2、海量数据分析。3、测试职位问的线程安全和非线程安全。4、HTTP2.0、thrift。5、面试电话沟通可能先让自我介绍。6、分布式事务一致性。7、ni
2023-01-26
胡喜平
我觉得《可见的学习》一书确实从底层逻辑说清楚了,教学的本质。可是太多术语和概念,一时间难以消化啊。而且知道和懂得有距离,运用就更不行了,需要高手和专家的指导。我需要多听听新课标的讲座了,来反复印证。读论文也有了一点点灵感,明天修改我的论文。
学生把我的课件换成小三认罪书(赵书晴宋诗月)全集阅读_学生把我的课件换成小三认罪书最新章节阅读_赵书晴宋诗月(学生把我的课件换成小三认罪书)全本免费在线阅读_(学生把我的课件换成小三认罪书)完结...
笔趣阁热门小说
学生把我的课件换成小三认罪书(赵书晴宋诗月)全集阅读_学生把我的课件换成小三认罪书最新章节阅读_赵书晴宋诗月(学生把我的课件换成小三认罪书)全本免费在线阅读_(学生把我的课件换成小三认罪书)完结版免费在线阅读_学生把我的课件换成小三认罪书(赵书晴宋诗月)完整版免费阅读_(学生把我的课件换成小三认罪书)全章节免费在线阅读主角配角:赵书晴宋诗月简介:我和赵京立去了民政局提交了申请因为离婚冷静期,还要再
图论算法经典题目解析:DFS、BFS与拓扑排序实战
周童學
数据结构与算法 深度优先 算法 图论
图论算法经典题目解析:DFS、BFS与拓扑排序实战图论问题是算法面试中的高频考点,本博客将通过四道LeetCode经典题目(均来自"Top100Liked"题库),深入讲解图论的核心算法思想和实现技巧。涵盖DFS、BFS、拓扑排序和前缀树等知识点,每道题配有Java实现和易错点分析。1.岛屿数量(DFS遍历)问题描述给定一个由'1'(陆地)和'0'(水)组成的二维网格,计算岛屿的数量。岛屿由水平或
【异常】使用 LiteFlow 框架时,提示错误ChainDuplicateException: [chain name duplicate] chainName=categoryChallenge
本本本添哥
002 - 进阶开发能力 java
一、报错内容Causedby:com.yomahub.liteflow.exception.ChainDuplicateException:[chainnameduplicate]chainName=categoryChallengeatcom.yomahub.liteflow.parser.helper.ParserHelper.lambda$null$0(ParserHelper.java:1
Java并发核心:线程池使用技巧与最佳实践! | 多线程篇(五)
bug菌¹
Java实战(进阶版) java Java零基础入门 Java并发 线程池 多线程篇
本文收录于「Java进阶实战」专栏,专业攻坚指数级提升,希望能够助你一臂之力,帮你早日登顶实现财富自由;同时,欢迎大家关注&&收藏&&订阅!持续更新中,up!up!up!!环境说明:Windows10+IntelliJIDEA2021.3.2+Jdk1.8本文目录前言摘要正文何为线程池?为什么需要线程池?线程池的好处线程池使用场景如何创建线程池?线程池的常见配置源码解析案例分享案例代码演示案例运行
Java 队列
tryxr
java 开发语言 队列
队列一般用什么哪种结构实现队列的特性数据入队列时一定是从尾部插入吗数据出队列时一定是从头部删除吗队列的基本运算有什么队列支持随机访问吗队列的英文表示什么是队列队列从哪进、从哪出队列的进出顺序队列是用哪种结构实现的Queue和Deque有什么区别Queue接口的方法Queue中的add与offer的区别offer、poll、peek的模拟实现如何利用链表实现队列如何利用顺序表实现队列什么叫做双端队列
JVM 内存分配与回收策略:从对象创建到内存释放的全流程
在JVM的运行机制中,内存分配与回收策略是连接对象生命周期与垃圾收集器的桥梁。它决定了对象在堆内存中的创建位置、存活过程中的区域迁移,以及最终被回收的时机。合理的内存分配策略能减少GC频率、降低停顿时间,是优化Java应用性能的核心环节。本文将系统解析JVM的内存分配规则、对象晋升机制,以及实战中的内存优化技巧。一、对象优先在Eden区分配:新生代的“临时缓冲区”大多数情况下,Java对象在新生代
代码随想录算法训练营第三十五天
01背包问题二维题目链接01背包问题二维题解importjava.util.Scanner;publicclassMain{publicstaticvoidmain(String[]args){Scannersc=newScanner(System.in);intM=sc.nextInt();intN=sc.nextInt();int[]space=newint[M];int[]value=new
人民日报每日金句摘抄精选8.1
飞云写作
1.岁月因青春慨然以赴而更加静好,世间因少年挺身向前而更加瑰丽。2.与其朋友圈字斟句酌,不如现实中好好生活。3.真正的优秀不是别人逼出来的,而是自己和自己死磕。4.时代的考题已经列出,我们的答卷正在写就。5.人生不就是这样,经历过一次次考验才能成长;人生不就是这样,哪怕雨雪霏霾也要去追寻阳光。6.忆往昔,百年征程砥砺“同心”;看今朝,千秋伟业催人奋进。7.真理的波涛,喷涌而出就奔流不息;理想的火焰
uniapp微信小程序 - 详解微信小程序平台用户授权登录全流程,uniapp v3版本中小程序端开发下用户点击登录后获取手机号/昵称/性别/头像等信息完成登录(提供完整示例代码,一键复制开箱即用)
十一猫咪爱养鱼
前端组件与功能(开箱即用) uniapp常见问题解决 uniapp vue3 uniapp3小程序授权登录 微信小程序登录获取用户信息教程 获取用户昵称手机号头像信息登录 vue3版本小程序平台授权登录 uniap小程序端用户登录流程 uni完整的小程序平台登录源码
效果图在uniapp微信小程序端开发中,超详细实现用户授权登录完整功能源码,用户授权后获取手机号/昵称/头像/性别等,提供完整思路流程及逻辑讲解。uniappVue3和Vue2都能用,你也可以直接复制粘贴,然后改下参数放到你的项目中去就行。整体思路做功能之前,先来看一下整体流程是
python笔记14介绍几个魔法方法
抢公主的大魔王
python python
python笔记14介绍几个魔法方法先声明一下各位大佬,这是我的笔记。如有错误,恳请指正。另外,感谢您的观看,谢谢啦!(1).__doc__输出对应的函数,类的说明文档print(print.__doc__)print(value,...,sep='',end='\n',file=sys.stdout,flush=False)Printsthevaluestoastream,ortosys.std
微信公众号回调java_处理微信公众号消息回调
weixin_39607620
微信公众号回调java
1、背景在上一节中,咱们知道如何接入微信公众号,可是以后公众号会与咱们进行交互,那么微信公众号如何通知到咱们本身的服务器呢?咱们知道咱们接入的时候提供的url是GET/mp/entry,那么公众号以后产生的事件将会以POST/mp/entry发送到咱们本身的服务器上。html2、代码实现,此处仍是使用weixin-java-mp这个框架实现一、引入weixin-java-mpcom.github.
Anaconda 和 Miniconda:功能详解与选择建议
古月฿
python入门 python conda
Anaconda和Miniconda详细介绍一、Anaconda的详细介绍1.什么是Anaconda?Anaconda是一个开源的包管理和环境管理工具,在数据科学、机器学习以及科学计算领域发挥着关键作用。它以Python和R语言为基础,为用户精心准备了大量预装库和工具,极大地缩短了搭建数据科学环境的时间。对于那些想要快速开展数据分析、模型训练等工作的人员来说,Anaconda就像是一个一站式的“数
环境搭建 | Python + Anaconda / Miniconda + PyCharm 的安装、配置与使用
本文将分别介绍Python、Anaconda/Miniconda、PyCharm的安装、配置与使用,详细介绍Python环境搭建的全过程,涵盖Python、Pip、PythonLauncher、Anaconda、Miniconda、Pycharm等内容,以官方文档为参照,使用经验为补充,内容全面而详实。由于图片太多,就先贴一个无图简化版吧,详情请查看Python+Anaconda/Minicond
你竟然还在用克隆删除?Conda最新版rename命令全攻略!
曦紫沐
Python基础知识 conda 虚拟环境管理
文章摘要Conda虚拟环境管理终于迎来革命性升级!本文揭秘Conda4.9+版本新增的rename黑科技,彻底告别传统“克隆+删除”的繁琐操作。从命令解析到实战案例,手把手教你如何安全高效地重命名Python虚拟环境,附带版本检测、环境迁移、故障排查等进阶技巧,助你提升开发效率10倍!一、颠覆认知:Conda居然自带重命名功能?很多开发者仍停留在“Conda无法直接重命名环境”的认知阶段,实际上自
[spring6: Mvc-网关]-源码解析
推荐阅读:[spring6:Mvc-函数式编程]-源码解析GatewayServerMvcAutoConfiguration@AutoConfiguration(after={HttpClientAutoConfiguration.class,RestTemplateAutoConfiguration.class,RestClientAutoConfiguration.class,FilterAu
centos7安装配置 Anaconda3
Anaconda是一个用于科学计算的Python发行版,Anaconda于Python,相当于centos于linux。下载[root@testsrc]#mwgethttps://mirrors.tuna.tsinghua.edu.cn/anaconda/archive/Anaconda3-5.2.0-Linux-x86_64.shBegintodownload:Anaconda3-5.2.0-L
Pandas:数据科学的超级瑞士军刀
科技林总
DeepSeek学AI 人工智能
**——从零基础到高效分析的进化指南**###**一、Pandas诞生:数据革命的救世主****2010年前的数据分析噩梦**:```python#传统Python处理表格数据data=[]forrowincsv_file:ifrow[3]>100androw[2]=="China":data.append(float(row[5])#代码冗长易错!```**核心痛点**:-Excel处理百万行崩
分布式链路追踪系统架构设计:从理论到企业级实践
ma451152002
java 分布式 系统架构
分布式链路追踪系统架构设计:从理论到企业级实践本文深入探讨分布式链路追踪系统的架构设计原理、关键技术实现和企业级应用实践,为P7架构师提供完整的技术方案参考。目录引言:分布式链路追踪的重要性核心概念与技术原理系统架构设计数据模型与协议标准核心组件架构设计性能优化与扩展性设计企业级实施策略技术选型与对比分析监控与运维体系未来发展趋势P7架构师面试要点引言:分布式链路追踪的重要性微服务架构下的挑战在现
java Illegal overloaded getter method with ambiguous type for propert的解决
zwllxs
java jdk
好久不来iteye,今天又来看看,哈哈,今天碰到在编码时,反射中会抛出
Illegal overloaded getter method with ambiguous type for propert这么个东东,从字面意思看,是反射在获取getter时迷惑了,然后回想起java在boolean值在生成getter时,分别有is和getter,也许我们的反射对象中就有is开头的方法迷惑了jdk,
IT人应当知道的10个行业小内幕
beijingjava
工作 互联网
10. 虽然IT业的薪酬比其他很多行业要好,但有公司因此视你为其“佣人”。
尽管IT人士的薪水没有互联网泡沫之前要好,但和其他行业人士比较,IT人的薪资还算好点。在接下的几十年中,科技在商业和社会发展中所占分量会一直增加,所以我们完全有理由相信,IT专业人才的需求量也不会减少。
然而,正因为IT人士的薪水普遍较高,所以有些公司认为给了你这么多钱,就把你看成是公司的“佣人”,拥有你的支配
java 实现自定义链表
CrazyMizzz
java 数据结构
1.链表结构
链表是链式的结构
2.链表的组成
链表是由头节点,中间节点和尾节点组成
节点是由两个部分组成:
1.数据域
2.引用域
3.链表的实现
&nbs
web项目发布到服务器后图片过一会儿消失
麦田的设计者
struts2 上传图片 永久保存
作为一名学习了android和j2ee的程序员,我们必须要意识到,客服端和服务器端的交互是很有必要的,比如你用eclipse写了一个web工程,并且发布到了服务器(tomcat)上,这时你在webapps目录下看到了你发布的web工程,你可以打开电脑的浏览器输入http://localhost:8080/工程/路径访问里面的资源。但是,有时你会突然的发现之前用struts2上传的图片
CodeIgniter框架Cart类 name 不能设置中文的解决方法
IT独行者
CodeIgniter Cart 框架
今天试用了一下CodeIgniter的Cart类时遇到了个小问题,发现当name的值为中文时,就写入不了session。在这里特别提醒一下。 在CI手册里也有说明,如下:
$data = array(
'id' => 'sku_123ABC',
'qty' => 1,
'
linux回收站
_wy_
linux 回收站
今天一不小心在ubuntu下把一个文件移动到了回收站,我并不想删,手误了。我急忙到Nautilus下的回收站中准备恢复它,但是里面居然什么都没有。 后来我发现这是由于我删文件的地方不在HOME所在的分区,而是在另一个独立的Linux分区下,这是我专门用于开发的分区。而我删除的东东在分区根目录下的.Trash-1000/file目录下,相关的删除信息(删除时间和文件所在
jquery回到页面顶端
知了ing
html jquery css
html代码:
<h1 id="anchor">页面标题</h1>
<div id="container">页面内容</div>
<p><a href="#anchor" class="topLink">回到顶端</a><
B树、B-树、B+树、B*树
矮蛋蛋
B树
原文地址:
http://www.cnblogs.com/oldhorse/archive/2009/11/16/1604009.html
B树
即二叉搜索树:
1.所有非叶子结点至多拥有两个儿子(Left和Right);
&nb
数据库连接池
alafqq
数据库连接池
http://www.cnblogs.com/xdp-gacl/p/4002804.html
@Anthor:孤傲苍狼
数据库连接池
用MySQLv5版本的数据库驱动没有问题,使用MySQLv6和Oracle的数据库驱动时候报如下错误:
java.lang.ClassCastException: $Proxy0 cannot be cast to java.sql.Connec
java泛型
百合不是茶
java泛型
泛型
在Java SE 1.5之前,没有泛型的情况的下,通过对类型Object的引用来实现参数的“任意化”,任意化的缺点就是要实行强制转换,这种强制转换可能会带来不安全的隐患
泛型的特点:消除强制转换 确保类型安全 向后兼容
简单泛型的定义:
泛型:就是在类中将其模糊化,在创建对象的时候再具体定义
class fan
javascript闭包[两个小测试例子]
bijian1013
JavaScript JavaScript
一.程序一
<script>
var name = "The Window";
var Object_a = {
name : "My Object",
getNameFunc : function(){
var that = this;
return function(){
探索JUnit4扩展:假设机制(Assumption)
bijian1013
java Assumption JUnit 单元测试
一.假设机制(Assumption)概述 理想情况下,写测试用例的开发人员可以明确的知道所有导致他们所写的测试用例不通过的地方,但是有的时候,这些导致测试用例不通过的地方并不是很容易的被发现,可能隐藏得很深,从而导致开发人员在写测试用例时很难预测到这些因素,而且往往这些因素并不是开发人员当初设计测试用例时真正目的,
【Gson四】范型POJO的反序列化
bit1129
POJO
在下面这个例子中,POJO(Data类)是一个范型类,在Tests中,指定范型类为PieceData,POJO初始化完成后,通过
String str = new Gson().toJson(data);
得到范型化的POJO序列化得到的JSON串,然后将这个JSON串反序列化为POJO
import com.google.gson.Gson;
import java.
【Spark八十五】Spark Streaming分析结果落地到MySQL
bit1129
Stream
几点总结:
1. DStream.foreachRDD是一个Output Operation,类似于RDD的action,会触发Job的提交。DStream.foreachRDD是数据落地很常用的方法
2. 获取MySQL Connection的操作应该放在foreachRDD的参数(是一个RDD[T]=>Unit的函数类型),这样,当foreachRDD方法在每个Worker上执行时,
NGINX + LUA实现复杂的控制
ronin47
nginx lua
安装lua_nginx_module 模块
lua_nginx_module 可以一步步的安装,也可以直接用淘宝的OpenResty
Centos和debian的安装就简单了。。
这里说下freebsd的安装:
fetch http://www.lua.org/ftp/lua-5.1.4.tar.gz
tar zxvf lua-5.1.4.tar.gz
cd lua-5.1.4
ma
java-递归判断数组是否升序
bylijinnan
java
public class IsAccendListRecursive {
/*递归判断数组是否升序
* if a Integer array is ascending,return true
* use recursion
*/
public static void main(String[] args){
IsAccendListRecursiv
Netty源码学习-DefaultChannelPipeline2
bylijinnan
java netty
Netty3的API
http://docs.jboss.org/netty/3.2/api/org/jboss/netty/channel/ChannelPipeline.html
里面提到ChannelPipeline的一个“pitfall”:
如果ChannelPipeline只有一个handler(假设为handlerA)且希望用另一handler(假设为handlerB)
来
Java工具之JPS
chinrui
java
JPS使用
熟悉Linux的朋友们都知道,Linux下有一个常用的命令叫做ps(Process Status),是用来查看Linux环境下进程信息的。同样的,在Java Virtual Machine里面也提供了类似的工具供广大Java开发人员使用,它就是jps(Java Process Status),它可以用来
window.print分页打印
ctrain
window
function init() {
var tt = document.getElementById("tt");
var childNodes = tt.childNodes[0].childNodes;
var level = 0;
for (var i = 0; i < childNodes.length; i++) {
安装hadoop时 执行jps命令Error occurred during initialization of VM
daizj
jdk hadoop jps
在安装hadoop时,执行JPS出现下面错误
[slave16]
[email protected] :/tmp/hsperfdata_hdfs# jps
Error occurred during initialization of VM
java.lang.Error: Properties init: Could not determine current working
PHP开发大型项目的一点经验
dcj3sjt126com
PHP 重构
一、变量 最好是把所有的变量存储在一个数组中,这样在程序的开发中可以带来很多的方便,特别是当程序很大的时候。变量的命名就当适合自己的习惯,不管是用拼音还是英语,至少应当有一定的意义,以便适合记忆。变量的命名尽量规范化,不要与PHP中的关键字相冲突。 二、函数 PHP自带了很多函数,这给我们程序的编写带来了很多的方便。当然,在大型程序中我们往往自己要定义许多个函数,几十
android笔记之--向网络发送GET/POST请求参数
dcj3sjt126com
android
使用GET方法发送请求
private static boolean sendGETRequest (String path,
Map<String, String> params) throws Exception{
//发送地http://192.168.100.91:8080/videoServi
linux复习笔记 之bash shell (3) 通配符
eksliang
linux 通配符 linux通配符
转载请出自出处:
http://eksliang.iteye.com/blog/2104387
在bash的操作环境中有一个非常有用的功能,那就是通配符。
下面列出一些常用的通配符,如下表所示 符号 意义 * 万用字符,代表0个到无穷个任意字符 ? 万用字符,代表一定有一个任意字符 [] 代表一定有一个在中括号内的字符。例如:[abcd]代表一定有一个字符,可能是a、b、c
Android关于短信加密
gqdy365
android
关于Android短信加密功能,我初步了解的如下(只在Android应用层试验):
1、因为Android有短信收发接口,可以调用接口完成短信收发;
发送过程:APP(基于短信应用修改)接受用户输入号码、内容——>APP对短信内容加密——>调用短信发送方法Sm
asp.net在网站根目录下创建文件夹
hvt
.net C# hovertree asp.net Web Forms
假设要在asp.net网站的根目录下建立文件夹hovertree,C#代码如下:
string m_keleyiFolderName = Server.MapPath("/hovertree");
if (Directory.Exists(m_keleyiFolderName))
{
//文件夹已经存在
return;
}
else
{
try
{
D
一个合格的程序员应该读过哪些书
justjavac
程序员 书籍
编者按:2008年8月4日,StackOverflow 网友 Bert F 发帖提问:哪本最具影响力的书,是每个程序员都应该读的?
“如果能时光倒流,回到过去,作为一个开发人员,你可以告诉自己在职业生涯初期应该读一本, 你会选择哪本书呢?我希望这个书单列表内容丰富,可以涵盖很多东西。”
很多程序员响应,他们在推荐时也写下自己的评语。 以前就有国内网友介绍这个程序员书单,不过都是推荐数
单实例实践
跑龙套_az
单例
1、内部类
public class Singleton {
private static class SingletonHolder {
public static Singleton singleton = new Singleton();
}
public Singleton getRes
PO VO BEAN 理解
q137681467
VO DTO po
PO:
全称是 persistant object持久对象 最形象的理解就是一个PO就是数据库中的一条记录。 好处是可以把一条记录作为一个对象处理,可以方便的转为其它对象。
BO:
全称是 business object:业务对象 主要作用是把业务逻辑封装为一个对象。这个对
战胜惰性,暗自努力
金笛子
努力
偶然看到一句很贴近生活的话:“别人都在你看不到的地方暗自努力,在你看得到的地方,他们也和你一样显得吊儿郎当,和你一样会抱怨,而只有你自己相信这些都是真的,最后也只有你一人继续不思进取。”很多句子总在不经意中就会戳中一部分人的软肋,我想我们每个人的周围总是有那么些表现得“吊儿郎当”的存在,是否你就真的相信他们如此不思进取,而开始放松了对自己的要求随波逐流呢?
我有个朋友是搞技术的,平时嘻嘻哈哈,以
NDK/JNI二维数组多维数组传递
wenzongliang
二维数组 jni NDK
多维数组和对象数组一样处理,例如二维数组里的每个元素还是一个数组 用jArray表示,直到数组变为一维的,且里面元素为基本类型,去获得一维数组指针。给大家提供个例子。已经测试通过。
Java_cn_wzl_FiveChessView_checkWin( JNIEnv* env,jobject thiz,jobjectArray qizidata)
{
jint i,j;
int s