爬虫(Java实现)
说明:
使用了htmlparser库。
运行过程:
从某个网址开始,摘取网页中的链接,并通过广度搜索,对这些链接递归执行上述操作。
在以上过程中把网址存入数据库中。以防止搜索中出现环路。
但是,程序经常进入某个网站后,会一直扫描其中的二级域名。
于是数据库中会出现这种情况:
jack.art.com
han.art.com
bob.art.com
alice.art.com
rose.art.com
...
...
代码:
//Robot.java 1 package robot;
import java.net.*;
import java.sql.SQLException;
import java.util.Random;
import javax.swing.JOptionPane;
import org.htmlparser.*;
import org.htmlparser.filters.TagNameFilter;
import org.htmlparser.tags.LinkTag;
import org.htmlparser.util.NodeList;
import org.htmlparser.util.ParserException;
import mydb.DB;
public class Robot {
int ff=0;
int num=0;
//DB db;
Robot() throws MalformedURLException, SQLException{
DB.getConnect("localhost","3306","robot","root","142365");
DB.getSta();
String url0="http://www.youku.com";//"http://localhost";
/* DB.rs= DB.s.executeQuery("select count(*) from urls");
if(DB.rs.next())
{int n=DB.rs.getInt(1);
System.out.println(n );
Random random = new Random();
int ran = random.nextInt();
ran%=n;
ran=ran>0?ran:-ran;
System.out.println(ran );
DB.rs= DB.s.executeQuery("select * from urls");
int x=0;
while(DB.rs.next()&&x<ran){
System.out.println(DB.rs.getString(1)+"000" ); url0=DB.rs.getString(1);
x++;
}
}*/
//catchHref("http://localhost",num);
catchHref(url0,num);
}
boolean isEndLegal(String str){
if(str.endsWith("php")||str.endsWith("net/")||str.endsWith("com/")||str.endsWith("cn/")||str.endsWith("gov/")||str.endsWith("edu/")||str.endsWith("org/")||str.endsWith("net")||str.endsWith("com")||str.endsWith("cn")||str.endsWith("gov")||str.endsWith("edu")||str.endsWith("org")){
return true;
}
return false;
}
boolean catchHref(String hreft ,int num) throws MalformedURLException {
Parser parser =null;
NodeList nodelist=null;
String href = "http://www.baidu.com";
//db=new DB();
if(ff!=0)
if (!(hreft.startsWith("http")&&isEndLegal(hreft)&&!isInDatabase(hreft))) {
return false;
}
ff=1;
add(hreft);
System.out.println(num);
try {
parser = new Parser(hreft);
if(parser==null)return false;
} catch (ParserException e) {
return false;
//e.printStackTrace();
}
try {
nodelist = parser.parse(null);
} catch (ParserException e1) {
e1.printStackTrace();
}
if(nodelist==null)return false;
NodeFilter filter = new TagNameFilter("A");
if(filter==null)return false;
nodelist = nodelist.extractAllNodesThatMatch(filter, true);
if(nodelist==null)return false;
for (int i = 0; i < nodelist.size(); i++) {
LinkTag link = (LinkTag) nodelist.elementAt(i);
href = link.getAttribute("href");
if(href==null)return false;
System.out.println(href );
catchHref(href,num);
}
num++;
return true;
}
void add(String str){
try {
DB.s.execute("insert into urls2(url)values('"+str+"');");
DB.commit();
System.out.println("add");
} catch (SQLException e) {
//e.printStackTrace();return ;
//JOptionPane.showMessageDialog(null, "数据库添加失败");
//System.exit(-1);
}
return ;
}
boolean isInDatabase(String str){
try {
DB.rs= DB.s.executeQuery("select * from urls where url like'"+str+"%';");
if(DB.rs.next()){System.out.println(DB.rs);return true;}
} catch (SQLException e) {
e.printStackTrace();
JOptionPane.showMessageDialog(null, "数据库查找失败");
System.exit(-1);
}
return false;
}
public static void main(String[] args)
throws MalformedURLException, ParserException, SQLException {
Robot robot = new Robot();
}
}
//DB.java 1 package mydb;
import java.sql.*;
import java.util.ArrayList;
import javax.swing.*;
//import com.mysql.jdbc.Driver;
public class DB {
public static Connection conn = null;
public static ResultSet rs = null;
public static Statement s = null;
public DB() {
conn = null;
s = null;
rs=null;
}
/*
String getResult(ResultSet rs) {
String str = "Book\t\tOwnerID\tOwnerName\n";
// System.out.println("\nno\tname\tsex\tsalary");
try {
while (rs.next()) {
StringBuilder builder = new StringBuilder(rs.getString(1));
builder.append("\t\t");
builder.append(rs.getString(2));
builder.append("\t");
builder.append(rs.getString(3));
builder.append("\n");
str += builder.toString();
}
} catch (Throwable e) {
}
// System.out.println();
return str;
}*/
public static Connection getConnect(String IP,String port,String database,String user,String password){
try {
// Class.forName("org.gjt.mm.mysql.Driver").newInstance();
Class.forName("com.mysql.jdbc.Driver");
} catch (ClassNotFoundException e1) {
e1.printStackTrace();
JOptionPane.showMessageDialog(null, "数据库包未找到");
System.exit(-1);
} // .newInstance();
try {
conn = DriverManager.getConnection(
"jdbc:mysql://"+IP+":"+port+"/"+database+"?useUnicode=true&characterEncoding=utf8", user,
password);//autoReconnect=true&useUnicode=true&characterEncoding=utf8
} catch (SQLException e1) {
e1.printStackTrace();
JOptionPane.showMessageDialog(null, "数据库无法连接");
System.exit(-1);
}
try {
conn.setAutoCommit(false);
} catch (SQLException e1) {
e1.printStackTrace();
}
return conn;
}
public static Statement getSta(){
try {
s = conn.createStatement();
} catch (SQLException e1) {
e1.printStackTrace();
JOptionPane.showMessageDialog(null, "无法建立数据库语句");
System.exit(-1);
}
return s;
}
public static int commit(){
try {
conn.commit();
} catch (SQLException e) {
e.printStackTrace();
JOptionPane.showMessageDialog(null, "对数据库更改无法应用");
}
return 0;
}
public static void closeConnect() {
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
JOptionPane.showMessageDialog(null, "数据库结果集无法关闭");
}
try {
s.close();
} catch (SQLException e) {
e.printStackTrace();
JOptionPane.showMessageDialog(null, "数据库语句无法关闭");
}
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
JOptionPane.showMessageDialog(null, "与数据库的连接无法关闭");
}
/*
try { // perform a clean shutdown
DriverManager.getConnection("jdbc:derby:;shutdown=true");
} catch (SQLException se) {
if (((se.getErrorCode() == 50000)
&& ("XJ015".equals(se.getSQLState())))) {
// we got the expected exception
System.out.println("Derby shut down normally");
// Note that for single database shutdown, the expected
// SQL state is "08006", and the error code is 45000.
} else {
System.err.println("Derby did not shut down normally");
// JOptionPane.showMessageDialog(null, "数据库关闭错误");
se.printStackTrace();
}
}*/
}
}
程序写于大三上学期。
2016.4.12更新博客。
END
爬虫(Java实现)的更多相关文章
- 老李分享:网页爬虫java实现
老李分享:网页爬虫java实现 poptest是国内唯一一家培养测试开发工程师的培训机构,以学员能胜任自动化测试,性能测试,测试工具开发等工作为目标.如果对课程感兴趣,请大家咨询qq:908821 ...
- CVE漏洞爬虫java代码依赖-TestNG
TestNG是Java中的一个测试框架,而该CVE漏洞爬虫示例中所涉及到的java代码中, \Crawler\src\com\***\ThreaderRun.java文件在导入import org.t ...
- 初入爬虫(java)
public class CrawlerUtil { public static void main(String [] args) throws IOException { // 创建默认的http ...
- 多线程爬虫Java调用wget下载文件,独立线程读取输出缓冲区
写了个抓取appstore的,要抓取大量的app,本来是用httpclient,但是效果不理想,于是直接调用wget下载,但是由于标准输出.错误输出的原因会导致卡住,另外wget也会莫名的卡住. 所以 ...
- 网络爬虫Java实现抓取网页内容
package 抓取网页; import java.io.FileOutputStream;import java.io.IOException;import java.io.InputStream; ...
- SuperSpider(简书爬虫JAVA版)
* 建站数据SuperSpider(简书)* 本项目目的:* 为练习web开发提供相关的数据:* 主要数据包括:* 简书热门专题模块信息.对应模块下的热门文章.* 文章的详细信息.作者信息.* 评论区 ...
- 201521123081《java程序设计》 第13周学习总结
本次作业参考文件 正则表达式参考资料 1. 本周学习总结 以你喜欢的方式(思维导图.OneNote或其他)归纳总结多网络相关内容. 参考资料:XMind 2. 书面作业 Q1. 网络基础 1.1 比较 ...
- 201521123006 《java程序设计》 第13周学习总结
1. 本周学习总结 1.以你喜欢的方式(思维导图.OneNote或其他)归纳总结多网络相关内容. 2. 书面作业 1. 网络基础 1.1 比较ping www.baidu.com与ping cec.j ...
- 201521123010 《Java程序设计》第13周学习总结
1. 本周学习总结 以你喜欢的方式(思维导图.OneNote或其他)归纳总结多网络相关内容. 2. 书面作业 1. 网络基础 1.1 比较ping www.baidu.com与ping cec.jmu ...
- 201521123037 《Java程序设计》第13周学习总结
1. 本周学习总结 以你喜欢的方式(思维导图.OneNote或其他)归纳总结多网络相关内容. 2. 书面作业 1. 网络基础 1.1 比较ping www.baidu.com与ping cec.jmu ...
随机推荐
- EC笔记,第二部分:5.了解C++默默编写并调用哪些函数
5.了解C++默默编写并调用哪些函数 1.C++空类 C++会为一个空类建立以下函数 (1).默认构造函数 (2).默认拷贝构造函数 (3).析构函数 (4).赋值运算符(如果成员包含引用类型或con ...
- 2分钟在eclipse下使用SpringBoot搭建Spring MVC的WEB项目
1. 首先用eclipse创建一个maven工程, 普通maven工程即可 2. 修改pom如下: <?xml version="1.0" encoding="UT ...
- PHP学习资料下载
yii2教程以及手册 https://yunpan.cn/ckkhbccyqGVYg (提取码:09b8) mysql学习 链接: http://pan.baidu.com/s/1kUTC8tT 密码 ...
- java.lang.IllegalArgumentException: Illegal character in query at index 261
在BaseFragment中使用了LoadingPage,而LoadingPage的联网加载使用的是AsyncHttpClient.一直报java.lang.IllegalArgumentExcept ...
- B/S结构的流程简单概述
在介绍appl ication 对象之前,先简单介绍一些Web 服务器的实现原理. 对于大部分浏览器而言,它通常负责完成三件事情: (1)向远程服务器发送请求. (2)读取远程服务器返 ...
- 时钟周期,CPU周期,指令周期,CPU时间片
从小到大来说:时钟周期,CPU周期,指令周期,CPU时间片 时钟周期:一个脉冲需要的时间,频率的倒数 CPU周期:读取一个指令节所需的时间 指令周期:读取并执行完一个指令所需的时间 CPU时间片:CP ...
- HTTP 2.0与HTTP 1.1区别
1.什么是HTTP 2.0 HTTP/2(超文本传输协议第2版,最初命名为HTTP 2.0),是HTTP协议的的第二个主要版本,使用于万维网.HTTP/2是HTTP协议自1999年HTTP 1.1发布 ...
- 浅谈C# 多态的法力
前言:我们都知道面向对象的三大特性:封装,继承,多态.封装和继承对于初学者而言比较好理解,但要理解多态,尤其是深入理解,初学者往往存在有很多困惑,为什么这样就可以?有时候感觉很不可思议,由此,面向对象 ...
- Jsp静态包含和动态包含的区别
1 <%@include file="xxx.jsp"%>为jsp中的编译指令,其文件的包含是发生在jsp向servlet转换的时期,而<jsp:include ...
- MVC中实现Area几种方法
概述 ASP.NET MVC中,是依靠某些文件夹以及类的固定命名规则去组织model实体层,views视图层和控制层的.如果是大规模的应用程序,经常会由不同功能的模块组成,而每个功能模块 ...