最近公司叫我这个实习生去写一个爬虫,将爬取到的数据存到数据库中,再通过前端界面渲染出来,这可是一个大难题啊,我从来没写过爬虫,最近学了一下,写了一个爬虫实例,并将其存到了数据库中,现在分享给大家。
这里我们用的是jsoup来写爬虫实例
首先我们先导入jar包依赖
,我们可以理一理,我们需要的依赖,除了创建web应用的基本依赖,我们还需要jsoup的jar包依赖,与数据库相关的,jdbc,mysql驱动,mybatis,就这三个,对了,我们创建的是springboot项目哦
现在我们来写代码
我们先创建一个类,用来单独写爬取页面的方法
package com.example.reptile2.utils;
import com.example.reptile2.pojo.Lottery;
import com.example.reptile2.service.HtmlParse;
import lombok.SneakyThrows;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
/**
* @ClassName HtmlParseUtil
* @Description TODO
* @Author ht
* @Date 2020/8/25 16:54
* @Version 1.0
**/
@Component
public class HtmlParseUtil {
public List<Lottery> parseBidding() throws IOException {
String url = "http://202.61.88.152:9002/view/staticpags/gkzbcggg/2020-08-25/46b14f6cbf12468a9ea473ebd0f12b82.html";
//获取该url,如果在30秒过后没有获取到,就放弃
//解析网页,(jsoup返回的Document就是;浏览器Document对象
Document document = null;
document = Jsoup.parse(new URL(url), 30000);
//所有在js中可以使用的都可以用,获取div名称类型为class其名称为tableBox的数据,就是获取到div中id名称为myPrintArea对的div框中的数据,只是这个div的class的名称为tableBox
Element element = document.getElementById("myPrintArea");
//获取所有的table标签
Elements elements = document.getElementsByTag("table");
//创建一个数组
ArrayList<Lottery> list = new ArrayList();
//这里的内容,这里的el就是每一个table标签
for (Element el : elements) {
//获取第一个class名称为bordertt confont的数据,第一个出现的数据,索引为0
String number = el.getElementsByClass("bordertt confont").eq(0).text();
//项目名称
String name = el.getElementsByClass("bordertt confont").eq(1).text();
//
String price = el.getElementsByClass("rowheight rightwidth bordertt confont").eq(0).text();
Lottery lottery = new Lottery();
// System.out.println("=====================================");
//
// System.out.println(number);
// System.out.println(name);
// System.out.println(price);
lottery.setNumber(number);
lottery.setName(name);
lottery.setPrice(price);
list.add(lottery);
}
return list;
}
}
那些document.getElementById,getElementsByTag啊什么的就不用我多说了把,就是js里面获取表现名的东西
一开始我是直接打印出来的,用来测试,后面我创建了一个对象Lottery
package com.example.reptile2.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @ClassName lottery
* @Description TODO
* @Author ht
* @Date 2020/8/26 9:18
* @Version 1.0
**/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Lottery {
private int id;
private String number;
private String name;
private String price;
}
将我们获取到的数据全部都存到对象里面,然后返回list集合,我这个界面它这些数据只有一个,可以直接返回对象,但是我返回集合,因为如果其他界面有,那还不是要返回集合,省事!
然后我们用@Compent标签将它放在容器中,但是我这里添加到了容器中,我也没有用标签调用,我直接new的
然后我们开始写逻辑了,我们的数据以及取出来了,下面我们应该思考怎么将它传到数据库中,我是直接用的三层架构的逻辑,一步一步写的,因为我就只会这个,哈哈哈
先创建service层
package com.example.reptile2.service;
import com.example.reptile2.pojo.Lottery;
import java.io.IOException;
import java.util.List;
/**
* @ClassName HtmlParse
* @Description TODO
* @Author ht
* @Date 2020/8/26 10:03
* @Version 1.0
**/
public interface HtmlParse {
public List<Lottery> parseBidding(Lottery lottery) throws IOException;
}
然后就是service的实现类serviceImpl
package com.example.reptile2.serviceImpl;
import com.example.reptile2.mapper.HtmlParseMapper;
import com.example.reptile2.pojo.Lottery;
import com.example.reptile2.service.HtmlParse;
import com.example.reptile2.utils.HtmlParseUtil;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.io.IOException;
import java.net.URL;
import java.util.List;
/**
* @ClassName HtmlParseImpl
* @Description TODO
* @Author ht
* @Date 2020/8/26 10:29
* @Version 1.0
**/
@Service
public class HtmlParseImpl implements HtmlParse {
@Autowired
HtmlParseMapper mapper;
@Override
public List<Lottery> parseBidding(Lottery lottery) throws IOException {
List<Lottery> list = new HtmlParseUtil().parseBidding();
lottery.setNumber(list.get(0).getNumber());
lottery.setName(list.get(0).getName());
lottery.setPrice(list.get(0).getPrice());
int count =mapper.parseBidding(lottery);
return list;
}
}
我这边直接获取值,因为我是数组,所有要用数组的方式,然后返回返回list
然后就是mapper层
package com.example.reptile2.mapper;
import com.example.reptile2.pojo.Lottery;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.stereotype.Repository;
import java.io.IOException;
import java.util.List;
/**
* @ClassName HtmlParseMapper
* @Description TODO
* @Author ht
* @Date 2020/8/26 10:06
* @Version 1.0
**/
@Mapper
@Repository
public interface HtmlParseMapper {
public int parseBidding(Lottery lottery) throws IOException;
}
以及mapper层的映射文件
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.reptile2.mapper.HtmlParseMapper">
<resultMap id="lottery" type="Lottery">
<result property="id" column="id"/>
<result property="number" column="number"/>
<result property="name" column="name"/>
<result property="price" column="price"/>
</resultMap>
<insert id="parseBidding" parameterType="com.example.reptile2.pojo.Lottery">
INSERT INTO lottery VALUE (#{id},#{number},#{name},#{price})
</insert>
</mapper>
还有就是Controller层了
package com.example.reptile2.controller;
import com.example.reptile2.pojo.Lottery;
import com.example.reptile2.service.HtmlParse;
import com.example.reptile2.serviceImpl.HtmlParseImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.io.IOException;
import java.util.List;
/**
* @ClassName HtmlParseController
* @Description TODO
* @Author ht
* @Date 2020/8/26 10:13
* @Version 1.0
**/
@RestController
public class HtmlParseController {
@Autowired
HtmlParseImpl htmlParseImpl;
@RequestMapping("insert")
public List<Lottery> insert(Lottery lottery) throws IOException {
List<Lottery> list =htmlParseImpl.parseBidding(lottery);
System.out.println(list);
return list;
}
}
controller层其实都没怎么写,因为我们主要的获取值得逻辑直接就写在了service层的实现类里面,这里只是用来创建一个接口的
这就是运行的结果,差不多就OK了
对了还有yaml的配置文件
#配置数据源
spring:
datasource:
username: 数据库用户名
password: 数据库密码
url: jdbc:mysql://0.0?serverTimezone=UTC&characterEncoding=UTF-8&userUnicode=true
driver-class-name: com.mysql.cj.jdbc.Driver
mybatis:
mapper-locations: classpath:/mybatis/*.xml
type-aliases-package: com.example.reptile2.pojo
#显示sql语句(初学者还是经常用一下)
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
这差不多就是我理解的东西了,大家不理解的可以去看看狂神的视频,我觉得讲的蛮好,不过我建议看的时候,可以先去看看java爬虫的基础,看了再看狂什么的就很不错
狂神视频网址
狂神视频jsoup网址
这次分析就到这里,继续用博客当笔记