声明:如需转载本篇文章,请进行私聊并在文章首处注明出处,本代码未经授权不可用于获取商业价值,否则后果将由自己承担。 这次的需求大概是从百度图片里面抓取任意的分类的图片,考虑到有些图片的资源不是很好,并且由于百度搜索越到后面相关度会越来越低,所以我将每个分类要爬的数据量控制在了600,实际爬下来,每个分类也就是500左右的图片。 实现架构 先来看一下本次代码的实现架构: htmlparse里面的两个类主要负责对网页进行请求以返回实体,并且对实体进行解析,拿到自己想要的json数据和每个图片的链接。 httpbrowser里面主要构建了要爬取的url,从百度图片的分页到具体的每个图片的url。 mainmethon主要就是main方法了。 savefile主要是将爬取的图片进行文件的保存,以每个图片的url最后面的一串字符串为文件名,然后将它保存到自己创建的目录之中。 我们来看一下main方法: package mainmethon; import httpbrowser.CreateUrl; impo 继续阅读 >>


董恒毅 17/05/21 02:05:27
定点爬取 当我们需要对金融行业的股票信息进行爬取的时候,由于股票的价格是一直在变化的,我们不可能手动的去每天定时定点的运行程序,这个时候我们就需要实现定点爬取了,我们引入第三方库quartz的使用: package timeutils; import org.quartz.CronTrigger; import org.quartz.JobDetail; import org.quartz.Scheduler; import org.quartz.SchedulerFactory; import org.quartz.impl.StdSchedulerFactory; import java.text.SimpleDateFormat; import java.util.Date; import static org.quartz.CronScheduleBuilder.cronSchedule; import static org.quartz.JobBuilder.newJob; import static org.quartz.TriggerB 继续阅读 >>


董恒毅 17/04/27 20:22:21
注:本文转载自:http://blog.csdn.net/zhanshen2015/article/details/51500757 C 语言的结构体可以将不同类型的对象聚合到一个对象中,在内存中,编译器按照成员列表顺序分别为每个结构体变量成员分配内存,但由于 C 的内存对齐机制以及不同机器间的差异,各个成员之间可能会有间隙,所以不能简单的通过成员类型所占的字长来推断其它成员或结构体对象的地址。 如果要计算结构体中某成员相对于该结构体首地址的偏移量,一般第一个反应就是该成员的地址与结构体对象的首地址之间的字节数,就比如我定义了这样一个结构体类型: typedef struct list_node { int ivar; char cvar; double dvar; struct list_node *next; }list_node; 就用这个类型来定义一个变量:list_node ln; 假设现在求 ln.dvar 的地址与 ln 的地址之间相差多少个字节,用这个表达式:(char )&ln.dvar - 继续阅读 >>


董恒毅 17/04/21 13:20:20
先来看看c语言printf函数运算顺序为什么从右到左? 从汇编角度来看,函数的参数总是从高地址压到低地址,而访问参数的时候又是通过基址加偏移量来的,所以按照逻辑,偏移量为0对应第一个参数,第一个参数在低地址,低地址最后压入栈,相对应的函数最右边的参数也就最先计算,并先压入栈。 一个由C/C++编译的程序的内存分布分为以下几个部分: 1、 栈(stack):也是我们所说的堆栈,是由编译器自动分配释放,用来存放函数参数值,函数的返回地址,非静态局部变量的值等。其操作方式类似于数据结构中的栈(后进先出LIFO)。 2、 堆(Heep):一般由程序员分配释放,若程序员不释放,程序结束可能由OS回收。 3、 全局区(静态区):全局变量和静态变量存储在这一块,初始化的全局变量和静态变量放在一块区域,未初始化的全局变量,静态变量放在相邻的另一块区域(BSS)。程序结束后由系统释放。 4、 文字常量区:常量字符串放在这个区域。 5、 程序代码区:存放函数体的二进制代码。 Linux下的内存映像布局一般有如下几个段(从低地址到高地址): 1 继续阅读 >>


董恒毅 17/04/20 20:22:35
1.向已经存在的数据库表添加一个新列: alter table 数据库表名 add column 列名 char(20) not null; 作者:championhengyi 发表于2017/4/14 18:04:23 原文链接 阅读:5 评论:0 查看评论 继续阅读 >>


董恒毅 17/04/14 18:04:23
final数据 在Java中,编译器可以将final常量代入任何可能用到它的计算式中,也就是说,可以在编译时进行计算,这减轻了一些运行时的负担。final常量必须是基本类型。 对于对象引用,final使引用恒定不变。一旦引用被初始化指向一个对象,就无法再把它改为指向另一个对象。然而,对象其自身却是可以被修改的,既是final又是static的域,将用大写表示,并使用下划线分割各个单词。 空白final 一个类中的final域可以做到根据对象不同而有所不同,却又保持恒定不变的特性。 public class BlankFinal { private final int i = 0; private final int j; private final Poppet p; public BlankFinal() { j = 1; p = new Poppet(1); } public BlankFinal(int x) { j = x; 继续阅读 >>


董恒毅 17/04/09 00:14:55
不管是哪种编程语言,都有一个很重要的问题,那就是成员的初始化,如果我们对自定义的变量没有进行适当的初始化,那么就有可能造成一些意想不到的错误,在写程序的时候,我们必须要对成员变量进行正确的初始化,所以今天我们就来讨论一下关于初始化的那些事。 先来看一些Java中有关初始化的小细节: 1.在方法中的局部变量未初始化的话编译器会报错,在类中则不会。 2.如果类的数据成员是基本类型的话,那么每个基本类型数据成员都会有一个初始值。 3.无法阻止自动初始化的进行,他们会在构造器被调用之前发生。 初始化顺序 在类的内部,变量定义的先后顺序决定了初始化的顺序,即使变量定义散布于方法定义之间,它们仍会在任何方法被调用之前得到初始化。(仔细理解这句话)举个例子: import static java.lang.System.out; /** * Created by paranoid on 17-3-22. * 由这个程序我们可以知道在创建一个对象的时候,变量定义的先后顺序决定了初始化的顺序。即使变量定义散布于 * 方法定义之间,他们仍旧会 继续阅读 >>


董恒毅 17/04/03 01:52:04
有时候,我们抓取下来一个html页面,发现浏览器页面可以显示的东西在html源码中却没有,这时候我们就要考虑服务器是以JSON格式将这部分数据发送到客户端的,对于这种情况的处理方式我们一般是在chrome的开发者工具中找到对应的JSON包,然后构建其URL,对JSON数据所在的源地址进行访问,然后使用一些工具对JSON数据进行解析,从而得到我们想要的东西。 阿里巴巴FastJson是一个Json处理工具包,包括“序列化”和“反序列化”两部分,它具备如下特征: 速度最快,测试表明,fastjson具有极快的性能,超越任其他的Java Json parser。包括自称最快的JackJson;功能强大,完全支持Java Bean、集合、Map、日期、Enum,支持范型,支持自省;无依赖,能够直接运行在Java SE 5.0以上版本;支持Android;开源 (Apache 2.0) 源码地址:https://github.com/alibaba/fastjson FastJson下载地址: http://download.csdn.net/detail/p 继续阅读 >>


董恒毅 17/04/02 20:42:45
从接触第一门编程语言开始我们就在不断强调,初始化变量是很重要的一件事情,尤其在C和C++中很明显,对于指针来说,定义一个指针不对它进行初始化,很有可能引发内存上的严重问题。但是我们也会常常忘记同样重要的清理工作。在Java中,垃圾回收器就负责回收无用对象占据的内存资源。 我们必须实施清理 在C++中,所有对象都会被销毁,或者说应该被销毁。如果C++创建了一个局部对象,此时的销毁动作发生在“右括号”为边界,此对象作用域的末尾处。如果对象是用new创建的,那么我们应该调用C++的delete操作符,也就会调用相应的析构函数,如果我们忘记调用delete,那么永远不会调用析构函数,这样就会出现内存泄漏,对象的其他部分也就得不到清理。 相反的是,Java不允许创建局部对象,必须使用new创建对象。在Java中也没有用于释放对象的delete,所以垃圾回收器会帮你释放存储空间。但是随着我们学习的深入,发现垃圾回收并不是万能的,也就是说我们不能认为垃圾回收器可以替代C++中的析构函数。所以如果我们希望进行除释放空间之外的清理工作,还是得明确调用某个恰当的Java 继续阅读 >>


董恒毅 17/03/31 22:35:15
this调用所操作对象的引用 问题1:假如统一类型的两个对象,分别是a和b,其中还有一个方法peel(),那么我们怎么才能分辨这个方法到底是被a调用还是被b调用呢? 其实,在这期间编译器做了一些事后工作,它暗自把“所操作对象的引用”作为地一个参数传递给了peel()。假设你希望在方法的内部获得对当前对象的引用,就可以使用this关键字。 代码如下: class Banana { void peel(int i){ out.println(i); } } public class BananaPeel { public static void main(String[] args){ Banana a = new Banana(); Banana b = new Banana(); a.peel(1); b.peel(2); } } Banana.peel(a, 1); Banana.peel(b, 2); 所以 继续阅读 >>


董恒毅 17/03/31 19:04:41