当前位置:   article > 正文

Java爬虫:大量抓取二手房信息并存入云端数据库过程详解(三)_爬取的广州二手房价数据怎么存储

爬取的广州二手房价数据怎么存储

这里详细讲一下将解析好的所有房源数据存入云端数据库的表中:
1、首先是获得数据库连接,Java提供了数据库链接的接口,但实现是由各个数据库提供者自己实现的,这里需要mysql提供的第三方包:mysql-connector-java-8.0.13.jar
、、新建一个类用于封装数据库处理的方法:

//封装数据库相关操作
public class OperationOfMySQL {
	
	//只创建一次链接
    Connection con;
    Statement state;
    
	public OperationOfMySQL() {
		super();
		this.con = connectionToDatabase();
		try {
		//state用于传入sql语句对数据库进行操作
			this.state = con.createStatement();
		} catch (Exception e) {
			System.out.println("链接失败!");
		}
	}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

如上面的代码,创建对象时就创建连接:
connectionToDatabase()方法返回获得的数据库链接:

//返回数据库链接的方法
	private static Connection connectionToDatabase() {
		Connection con = null;
		//创建驱动对象
		try {
		Driver driver = new Driver();
		String url = cloud;
		Properties info = new Properties();
		//准备数据库链接信息
		info.put("user", "rds_repl");
		info.put("password", "123456");
		//获取数据库链接
	    con = driver.connect(url, info);
		}catch (SQLException e) {
			System.out.println("链接数据库失败!");
			return null;
		}
		System.out.println(con+"\n链接创建成功!");
		return con;
	}
	//cloud是加载云端驱动的数据库,格式为:
	//String cloud = "jdbc:mysql://服务器地址:端口号/数据库名?severTimzone=UTC";
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

、、关于云端数据库的地址和端口号这里就不贴出来了(云端和本地的数据库链接其实方法一样),值得注意的是,如果用的是数据库连接池有必要设置一下链接超时,虽然我并没有这样做。。。

PS:还有就是8.0版本加载驱动的类是 com.mysql.cj.jdbc.Driver;多了个“cj”,所以必须设置时区:severTimezone=UTC,5.0版本的不用,不然运行时会报错。(在此只是提醒一下,具体原因就不细说了);

Java是通过state对象传递sql字符串给数据库。由于数据库事先存在,所以需要的是建一张表来存储房屋信息,键表语句为:

//如果数据库中不存在表house1就创建一张
static private String SQLCreateTaleStr = "CREATE TABLE IF NOT EXISTS house1" 
	+ "("
	+ "title varchar(255) ,"
	+ "area double ,"
	+ "price varchar(64) ,"
	+ "unit_price double ,"
	+ "direction varchar(64),"
	+ "decoration varchar(64),"
	+ "houseStyle varchar(64) ,"
	+ "floor varchar(64),"
	+ "buildTime int(11) ,"
	+ "community varchar(64),"
	+ "location varchar(64) ,"
	+ "gdpperperson double"
	+ ")ENGINE = InnoDB DEFAULT CHARSET = utf8;";
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

然后写一个方法将房屋信息转换成sql插入表的语句:

//用于生成插入语句的方法,传入一个房子和表的名字
	public String insertStr(SecondHouse house) {
		String insert = "insert into house1"
				+ " values('" 
				+house.getElemName()+    "','"
				+house.getArea()+        "','"
				+house.getPrice()+       "','"
				+house.getUnit_price()+  "','"
				+house.getDirection()+   "','"
				+house.getDecoration()+  "','"
				+house.getHouseStyle()+  "','"
				+house.getFloor()+       "','"
				+house.getBuildTime()+   "','"
				+house.getCommunity()+   "','"
				+house.getLocation()+    "','"
				+0+                      "');";
		return insert ;
	}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

PS;注意拼接字符串时的空格和标点,确保sql语句能够执行
然后是执行这写语句的方法:

//传入链接,进行对数据库的操作,传入二手房,写进数据库
	public void operationOnDtabase(String insertStr) {
		try {
		//获取执行sql语句动态创建表,即如果表不存在就创建一个
	    state.execute(SQLCreateTaleStr);
	    //执行插入语句
		state.executeUpdate(insertStr);
//		System.out.println(insertStr);
		}catch (SQLException e) {
			System.out.println("SQL语句执行失败!");
		}
		System.out.println("执行语句成功!");
	}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

工具方法都准备好了,需要将其整合:

//传入房屋数组,写入云端数据库,这里的houses数组就是先前存储所有房屋对象的vector集合转换的
	public static void writeIntoDtabase(SecondHouse[] houses) {
		OperationOfMySQL op = new OperationOfMySQL();
		for (int i = 0; i < houses.length; i++) {
			try {
//				SecondHouse.printHouseInfo(houses[i]);
				op.operationOnDtabase(op.insertStr(houses[i]));
			} catch (Exception e) {
				continue;
			}
		}
	}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

最后是main方法里面执行网页解析,多线程调用和写入数据库的所有实现;

//---------------------------main方法代替执行--------------------------------------------------------------------
	public static void operateMain() {
		houseSet = new Vector<>();
		//多线程集合
		Vector<Thread> threads = new Vector<>();
		for (int i = 1; i <= 50; i++) {
			Thread1 td1 = new Thread1(i, houseSet);
			threads.add(td1);
			td1.start();
		}
		
		for (int j = 51; j <=100; j++) {
			Thread2 td2 = new Thread2(j,houseSet);
			threads.add(td2);
			td2.start();
		}
		
		//等待所有子线程结束join方法
		for (Thread thread : threads) {
			try {
				thread.join();
			} catch (InterruptedException e) {
				System.out.println("执行失败!");
			}
		}
		//去除重复数据
		Vector<SecondHouse> houses = noneSameVector(houseSet);
		//写入数据库
		writeIntoDtabase(houses.toArray(new SecondHouse[houses.size()]));
	}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30

额,上面这个方法并不是main方法对吧,因为个爬虫要到导成jar包在一个小服务器上定时运行,所以我在main方法里面调用了这个方法,然后main里面实现定时运行了,这里就不贴出来了。

哦,还有那个去除重复的方法我没贴出来,实际上这个爬虫我解析了多个网站,难免会有相同的房屋信息,所以在这里就除重了,当然,传入sql语句在数据库里面除重更好。

讲一下写这个爬虫的收获:
、、确实感受到了Java语言的魅力所在,虽然并没有写出具有这种魅力的代码,Java无愧为第一语言(不要提PHP)。编程要有耐心,还要有持续学习和不断尝新的思想,开始写这个爬虫之前,对以上写的这些代码我一无所知,觉得都是些很高级的东西。然后,就结合学过的知识和网上了解到的处理方法来一步步实现,写完发现,其实也就那样,自己接触的这些不过是皮毛而已(可能连毛都不算),还需要再接再厉。

PS:这个爬虫有相当多的缺点和需要优化的地方,我没有细查了,不过基本功能可以正常实现,嗯。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Monodyee/article/detail/192507
推荐阅读
相关标签
  

闽ICP备14008679号