前言:
眼前各位老铁们对“java抓取数据”都比较讲究,我们都想要知道一些“java抓取数据”的相关知识。那么小编同时在网摘上搜集了一些对于“java抓取数据””的相关资讯,希望朋友们能喜欢,看官们快快来学习一下吧!添加依赖
<!--SpringMVC--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!--SpringData Jpa--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <!--MySQL连接包--> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.49</version> </dependency> <!-- HttpClient --> <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpclient</artifactId> </dependency> <!--Jsoup--> <dependency> <groupId>org.jsoup</groupId> <artifactId>jsoup</artifactId> <version>1.15.2</version> </dependency> <!--lombok--> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency>复制代码配置application.properties
# MySQL配置spring.datasource.driverClassName=com.mysql.jdbc.Driverspring.datasource.url=jdbc:mysql://localhost:3306/demo?useUnicode=true&characterEncoding=utf8spring.datasource.username=rootspring.datasource.password=123456# JPA配置spring.jpa.database=MySQLspring.jpa.show-sql=truespring.jpa.generate-ddl=truespring.jpa.hibernate.ddl-auto=updatespring.jpa.hibernate.naming_strategy=org.hibernate.cfg.ImprovedNamingStrategy复制代码POJO
@Entity@Table(name = "item")@Datapublic class Item { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; //标准产品单位 private Long spu; //库存量单位 private Long sku; //商品标题 private String title; //商品价格 private Double price; //商品图片 private String pic; //商品详情地址 private String url; //店铺; private String shop; //创建时间 private Date created; //更新时间 private Date updated;}复制代码Dao
public interface ItemDao extends JpaRepository<Item,Long> {}复制代码Service
public interface ItemService { /** * 保存商品 * * @param item */ void save(Item item); /** * 删除所有商品 */ void deleteAll();}@Servicepublic class ItemServiceImpl implements ItemService { @Autowired private ItemDao itemDao; @Override @Transactional public void save(Item item) { this.itemDao.save(item); } @Override public void deleteAll() { this.itemDao.deleteAll(); }}复制代码封装HttpClient
@Componentpublic class HttpUtils { private static final String FILEPATH = "D:\\demo\\"; private PoolingHttpClientConnectionManager cm; public HttpUtils() { this.cm = new PoolingHttpClientConnectionManager(); //设置最大连接数 this.cm.setMaxTotal(100); //设置每个主机的最大连接数 this.cm.setDefaultMaxPerRoute(10); } /** * 根据请求地址下载页面数据 * * @param url * @return 页面数据 */ public String doGetHtml(String url) { //获取HttpClient对象 CloseableHttpClient httpClient = HttpClients.custom().setConnectionManager(this.cm).build(); //创建httpGet请求对象,设置url地址 HttpGet httpGet = new HttpGet(url); httpGet.setHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36"); //设置请求信息 httpGet.setConfig(this.getConfig()); CloseableHttpResponse response = null; try { //使用HttpClient发起请求,获取响应 response = httpClient.execute(httpGet); //解析响应,返回结果 if (response.getStatusLine().getStatusCode() == 200) { //判断响应体Entity是否不为空,如果不为空就可以使用EntityUtils if (response.getEntity() != null) { String content = EntityUtils.toString(response.getEntity(), "utf8"); return content; } } } catch (IOException e) { e.printStackTrace(); } finally { //关闭response if (response != null) { try { response.close(); } catch (IOException e) { e.printStackTrace(); } } } //返回空串 return ""; } /** * 下载图片 * * @param url * @return 图片名称 */ public String doGetImage(String url) { //获取HttpClient对象 CloseableHttpClient httpClient = HttpClients.custom().setConnectionManager(this.cm).build(); //创建httpGet请求对象,设置url地址 HttpGet httpGet = new HttpGet(url); //设置请求信息 httpGet.setConfig(this.getConfig()); CloseableHttpResponse response = null; try { //使用HttpClient发起请求,获取响应 response = httpClient.execute(httpGet); //解析响应,返回结果 if (response.getStatusLine().getStatusCode() == 200) { //判断响应体Entity是否不为空 if (response.getEntity() != null) { //获取图片的后缀 String extName = url.substring(url.lastIndexOf(".")); //创建图片名,重命名图片 String picName = UUID.randomUUID() + extName; //声明OutPutStream OutputStream outputStream = new FileOutputStream(new File(FILEPATH + picName)); response.getEntity().writeTo(outputStream); //返回图片名称 return picName; } } } catch (IOException e) { e.printStackTrace(); } finally { //关闭response if (response != null) { try { response.close(); } catch (IOException e) { e.printStackTrace(); } } } //如果下载失败,返回空串 return ""; } /** * 设置请求信息 * * @return */ private RequestConfig getConfig() { RequestConfig config = RequestConfig.custom() //创建连接的最长时间 .setConnectTimeout(1000) // 获取连接的最长时间 .setConnectionRequestTimeout(500) //数据传输的最长时间 .setSocketTimeout(10000) .build(); return config; }}复制代码SPU与SKU
SPU
SPU是商品信息聚合的最小单位,是一组可复用、易检索的标准化信息的集合,该集合描述了一个产品的特性。
属性值、特性相同的商品就可以称为一个SPU。
如:某型号某配置某颜色的笔记本电脑就对应一个SPU,它有多种配置,或者多种颜色
SKU
SKU即库存进出计量的单位, 可以是以件、盒、托盘等为单位。SKU是物理上不可分割的最小存货单元。在使用时要根据不同业态,不同管理模式来处理。
如:某型号的笔记本电脑有多种配置,8G+512G笔记本电脑就是一个SKU。
爬取分析
爬取笔记本电脑搜索页面。进行分页操作,得到分页请求地址:
所有商品由一个class=J_goodsList的div包裹。div中则是由ul标签包裹的li标签,每一个li标签对应一个商品信息。
li标签包含的需要的商品信息
爬取逻辑
@Componentpublic class ItemTask { @Autowired private HttpUtils httpUtils; @Autowired private ItemService itemService; /** * 使用定时任务抓取最新数据 * * @throws Exception */ @Scheduled(fixedDelay = 50 * 1000) public void itemTask() throws Exception { // 每次执行前请客数据 itemService.deleteAll(); //声明需要解析的初始地址 String url = ";; // 按照页面对搜索结果进行遍历解析,注意页面是奇数 for (int i = 1; i < 10; i = i + 2) { String html = httpUtils.doGetHtml(url + i); // 解析页面,获取商品数据并存储 this.parse(html); } System.out.println("商品数据抓取完成!"); } /** * 解析页面,获取商品数据并存储 * * @param html * @throws Exception */ private void parse(String html) { // 解析html获取Document Document doc = Jsoup.parse(html); // 获取spu信息 Elements spuEles = doc.select("div#J_goodsList > ul > li"); // 循环列表中的SPU信息 for (int i = 0; i < spuEles.size(); i++) { Element element = spuEles.get(i); //获取spu String strSpu = element.attr("data-spu"); if (strSpu == null || strSpu.equals("")) { continue; } long spu = Long.parseLong(strSpu); //获取sku long sku = Long.parseLong(element.attr("data-sku")); Item item = new Item(); //设置商品的spu item.setSpu(spu); //设置商品的sku item.setSku(sku); //获取商品的详情的url String itemUrl = "; + sku + ".html"; item.setUrl(itemUrl); // 获取商品的图片 String picUrl = "https:" + element.select("div.p-img").select("a").select("img").attr("data-lazy-img"); String picName = this.httpUtils.doGetImage(picUrl); item.setPic(picName); //获取商品的价格 String strPrice = element.select("div.p-price").select("i").text(); item.setPrice(Double.parseDouble(strPrice)); //获取商品的标题 String title = element.select("div.p-name").select("a").attr("title"); item.setTitle(title); // 店铺名称 String shopName = element.select("div.p-shop a").text(); item.setShop(shopName); item.setCreated(new Date()); item.setUpdated(item.getCreated()); //保存商品数据到数据库中 this.itemService.save(item); } }}复制代码配置启动类
@SpringBootApplication// 开启定时任务@EnableSchedulingpublic class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); }}复制代码执行测试
启动项目,执行测试。查看数据库与本地下载照片。
标签: #java抓取数据