java抓取网页数据(java爬虫简单理解java的爬虫项目调试任务)

优采云 发布时间: 2022-02-24 22:15

  java抓取网页数据(java爬虫简单理解java的爬虫项目调试任务)

  一、任务:

  其目的是利用java爬虫提取网络中的各种商品信息,并建立统一的数据模型来存储采集到的商品信息中的数据,并通过数据模型描述商品的基本属性。如spu、sku、产品描述、价格等信息,需要剔除不必要的信息才能达到准确分析。根据获取的信息提供产品展示页面,通过搜索获取​​产品数据信息。采集产品数据,建立统一的数据模型,模型可扩展,展示产品数据。

  目的:本项目有利于简单了解java的爬虫流程,简单的项目调试,调用,映射方法,spring boot的数据库连接,前后端交互的原理,帮助理解。

  二、类与数据设计2.1项目开发环境

  

  2.2 系统功能结构设计

  程序主要使用爬虫功能通过调用webmagic来爬取数据,建立数据模型,使用MySQL存储数据。查询调用数据库内容,模型的扩展性,通过html/css提供网页展示。

  

  2.2.1数据爬取,数据模型建立

  网络魔术:

  

  WebMagic 的结构分为四大组件:Downloader、PageProcessor、Scheduler 和 Pipeline,它们由 Spider 组织。

  1)Downloader:负责从互联网上下载页面进行后续处理。WebMagic 默认使用 Apache HttpClient 作为下载工具。

  2)PageProcessor:负责解析页面,提取有用信息,发现新链接。WebMagic 使用 Jsoup 作为 HTML 解析工具,并在其基础上开发了 Xsoup,一个解析 XPath 的工具。这四个组件中,PageProcessor对于每个站点的每个页面都是不同的,是需要用户自定义的部分。

  3)Scheduler:负责管理要爬取的URL,以及一些去重工作。WebMagic 默认提供 JDK 的内存队列来管理 URL,并使用集合进行去重。还支持使用 Redis 进行分布式管理。除非项目有一些特殊的分布式需求,否则不需要自己定制Scheduler。

  4)Pipeline:负责提取结果的处理,包括计算、持久化到文件、数据库等。WebMagic默认提供两种结果处理方案:“输出到控制台”和“保存到文件”。Pipeline 定义了保存结果的方式。如果要保存到指定的数据库,需要编写相应的Pipeline。通常,对于一类需求,只需要编写一个 Pipeline。

  硒:

  Selenium 是一个用于 Web 的自动化测试工具。它可以根据我们的指令用代码控制浏览器,让浏览器自动加载页面,获取需要的数据,甚至对页面进行截图,或者判断网站上的某些动作是否发生。, 支持主流浏览器

  该程序使用 Downloader、PageProcessor、Pipeline 和 Spider 组件来爬取和构建数据模型。使用 selenium 自动化 Google 的无头浏览器。

  

  

  1、计划任务

  在 springboot 项目中使用计时器。在项目中创建一个普通类,添加注解@Component,

  在定义方法上使用@Scheduled注解,配置定时执行时间,在spring boot项目的boot类上添加@EnableScheduling注解。

  2、设置代理

  使用代理服务器发起请求,防止反爬策略阻塞ip

  代理服务器进程:

  爬虫服务器 -> 代理服务器 -> 目标服务器

  目标服务器->代理服务器->爬虫服务器->解析数据

  提供免费代理:

  免费私人代理 - 米扑代理

  3、使用selenium+headless浏览器抓取数据

  通过 Maven 添加 Selenium 依赖项。Selenium 是一个前端测试框架,通过 Selenium 使用代码来控制浏览器。

  无头浏览器:没有界面的浏览器,解析js。获取一些默认情况下不可用的数据。用于各种测试场景,可以在任何给定页面上执行的频繁重复操作,重复测试。

  4、使用浏览器渲染,抓取京东商城的数据并保存

  1)PageProcess 解析 html

  

  2)下载器下载页面

  

  3)管道保存到数据库

  5、模型可扩展性

  2.2.2?SpringBoot+Ajax+MyBatis查询操作数据库

  发展秩序

  

  

  实体层:存放实体类,其属性值与数据库值一致,实现setter和getter方法。

  Dao层:即mapper层,对数据库进行持久化操作。他的方法基本上是对数据库操作进行增删改查。作为接口,只有方法名,具体实现在mapper.xml中实现。

  服务层:业务层,存储业务逻辑处理,不直接对数据库进行操作,有接口和接口实现类,提供控制器层调用方法。

  控制器层:控制层,导入服务层,调用你的服务方法,控制器通过接受前端的参数进行业务操作,返回指定的路径或数据表。

  选择ajax的原因是爬虫操作数据量大,变化多。AJAX 可以提供一种无需重新加载整个网页即可更新部分网页的技术。AJAX 是一种用于创建快速和动态网页的技术。AJAX 可以通过在后台与服务器交换少量数据来异步更新网页。这意味着可以在不重新加载整个页面的情况下更新页面的某些部分。

  相反,选择 MyBatis,因为 MyBatis 可以使用简单的 XML 或注释进行配置,并将原语、映射接口和 POJO 映射到数据库记录。消除了大部分 JDBC 代码以及手动设置参数和检索结果。同时,基于 MyBatis 的灵活特性,不会对应用程序或数据库的现有设计造成任何影响。SQL采用XML编写,与程序代码完全分离,降低了耦合度,为程序的可扩展性提供了基础。

  

  ?三、部分代码3.1个爬虫部分

  @Override

public void process(Page page) {

String level = page.getRequest().getExtra("level").toString();

switch (level){

case "list":

parseList(page);

break;

case "detail":

praseDetail(page);

break;

}

/**

* 解析详情页

*

* @param page

*/

private void praseDetail(Page page) {

Html html = page.getHtml();

String title = html.$("div.master .p-name").xpath("///allText()").get();

String priceStr = html.$("div.summary-price-wrap .p-price span.price").xpath("///allText()").get();

String pic = "https:"+html.$("#spec-img").xpath("///@src").get();

String url = "https:"+html.$("div.master .p-name a").xpath("///@href").get();

String sku = html.$("a.notice.J-notify-sale").xpath("///@data-sku").get();

Item item = new Item();

item.setTitle(title);

item.setPic(pic);

item.setPrice(Float.valueOf(priceStr));

item.setUrl(url);

item.setUpdated(new Date());

item.setSku(StringUtils.isNotBlank(sku)?Long.valueOf(sku) : null);

// 单条数据塞入

page.putField("item", item);

}

/**

* 解析列表页

* @param page

*/

private void parseList(Page page) {

Html html = page.getHtml();

// 这里拿到sku 和 spu 并交给pipeline

List nodes = html.$("ul.gl-warp.clearfix > li").nodes();

List itemList = new ArrayList();

for (Selectable node : nodes) {

// 拿到sku和spu

String sku = node.$("li").xpath("///@data-sku").get();

String spu = node.$("li").xpath("///@data-spu").get();

String href = "https:" + node.$("div.p-img a").xpath("///@href").get();

Item item = new Item();

item.setSku(Long.valueOf(sku));

item.setSpu(StringUtils.isNotBlank(spu) ? Long.valueOf(spu) : 0);

item.setCreated(new Date());

itemList.add(item);

// 同时还需要把链接加到详情页 加到队列

Request request = new Request(href);

request.putExtra("level", "detail");

request.putExtra("pageNum", page.getRequest().getExtra("pageNum"));

request.putExtra("detailUrl", href);

page.addTargetRequest(request);

}

// 以集合的方式存入

page.putField("itemList", itemList);

// 同时还要去做分页

String pageNum = page.getRequest().getExtra("pageNum").toString();

if ("1".equals(pageNum)){

Request request = new Request("https://nextpage.com");

request.putExtra("level", "page"); // 标识去分页

request.putExtra("pageNum", (Integer.valueOf(pageNum) + 1) + "");// 页码要+1 接下来要的是第二页

// 添加到队列

page.addTargetRequest(request);

}

  3.2 spring boot 查询操作数据库

  Control控制层:

@RestController//返回rest服务类型的数据格式

@RequestMapping("/Jd")//数据接口controller怎么被调用

public class ItemController {

//调用一些方法得到返回值,把服务层作为对象

@Autowired//自动注入,生成实例

private ItemService itemService;//好封装

@GetMapping("/getJd")//路径如果是Jd下的getJd,会获得前端传来的参数‘id',获得值,把id值传到findById方法中

public String getItem(@Param("id")Integer id){

Item item = itemService.findById(id);

return item.getTitle();

}

@GetMapping("/getId") // 通过title// 获取id

public Integer getId(@Param("Message") String title){

Item item = itemService.findByTitle(title);

return item.getId();

}

@GetMapping("/getOne") // 通过title// 获取id,一条数据记录

public Item getAll(@Param("id") Integer id){

Item item = itemService.findById(id);

return item;

}

@GetMapping("/getJson") // 通过title获取id

public String getJson(@Param("id") Integer id) {

Item item = itemService.findById(id);

Gson gson = new Gson();

return gson.toJson(item);

}

@GetMapping("/getAll") // 通过title获取id,获得多条数据

public List getAll(){

List list = itemService.findItemAll();

return list;

}

@GetMapping("/getAllJson") // 通过title获取id

public String getAllJson(){

List list = itemService.findItemAll();

Gson gson = new Gson();

return gson.toJson(list);

}

}

  3.3前端设计

  

Title

$(document).ready(function(){

$("#btn1").click(function(){

test1();

});

$("#btn2").click(function(){

$.test2();

});

});

//data为数组

function test1(){

//alert("Text1: " + $("#test").text());

$.ajax({

url:'/msg/getAllJson',//访问后台接口,用get,后台返回json

type:'get',

dataType:'json',

success:function(data){

$("#tabletest").find('tr').remove();

tr='idtitle'

$("#tabletest").append(''+tr+'')

//方法中传入的参数data为后台获取的数据

for(i in data) //data指的是数组,i为数组的索引

{

var tr;

tr=''+data[i].id+''+''+data[i].title +''

$("#tabletest").append(''+tr+'')

}

}

});

}

.center{

margin: auto;

text-align:center;

font-size: 24px;

width: 60%;

background: lightblue;

}

<p id="test">Springboot整合MyBatis通过ajax查询MySQL数据库数据</b>

显示所有数据

查询

</p>

  四、程序运行、测试与分析4.1程序运行

  

  

  4.2 总结分析在使用java程序时,要注意jdk版本和jdk对应的数据库版本。使用数据库操作时,要注意数据库与idea的连接应用中url、用户名、密码的格式。注意传入数据文件路径的相对绝对路径。学会调试,逐步了解一个项目的流程,排除错误。在调试程序时,要深思熟虑,寻找解决办法,一一排除出错的原因。了解各种注解 API 的作用可以帮助您优化代码。对于种类繁多的技术,需要根据需求选择合适的、高效的、可扩展的技术。通过节目,我们对前后端的工作方式有了更深入的了解,对springboot的工作原理有了更深入的了解。4.3改进4.3.1对于爬虫:

  4.3.2.前端太丑太简单

0 个评论

要回复文章请先登录注册


官方客服QQ群

微信人工客服

QQ人工客服


线