200字范文,内容丰富有趣,生活中的好帮手!
200字范文 > Java实现网络爬虫:爬取京东商品案例

Java实现网络爬虫:爬取京东商品案例

时间:2019-12-21 14:19:12

相关推荐

Java实现网络爬虫:爬取京东商品案例

Java实现网络爬虫

爬取京东商品案例需求分析代码实现

爬取京东商品案例

需求分析

一、需求

抓取京东商城的数据,把商品数据保存到数据库。

二、功能分析

使用HttpClient发送一个get请求,请求搜索url,得到商品列表使用jsoup解析搜索结果页面。把商品信息封装一个对象中。把商品数据保存到数据库。

三、京东页面分析

当在京东的搜索框输入手机时,此时的url为

/Search?keyword=手机&wq=手机&page=1&s=1&click=1

当进行翻页操作,发现page值为1,3,5,7…进一步分析发现,京东商品每一页展示两页数据,当看完一页数据后,拉到底部,会显示第二页数据,当看完第二页数据,才会进行翻页操作,此时真正进入第二页。

问题:京东商城每次只展示30条数据,后30条数据(每页的第二页)是ajax动态加载的,使用HttpClient解决非常麻烦,此处不进行爬取后30条数据。

爬取页数:取10页数据。

爬取的信息:商品标题,价格,图片,skuid,spuid,商品详情地址等

四、数据库表创建

保存到数据库:创建一个数据库。需要的字段都是商品列表中可以解析出来的字段。

CREATE TABLE `jd_item` (`id` bigint(10) NOT NULL AUTO_INCREMENT COMMENT '主键id',`spu` bigint(15) DEFAULT NULL COMMENT '商品集合id',`sku` bigint(15) DEFAULT NULL COMMENT '商品最小品类单元id',`title` varchar(1000) DEFAULT NULL COMMENT '商品标题',`price` float(10,0) DEFAULT NULL COMMENT '商品价格',`pic` varchar(200) DEFAULT NULL COMMENT '商品图片',`url` varchar(1500) DEFAULT NULL COMMENT '商品详情地址',`created` datetime DEFAULT NULL COMMENT '创建时间',`updated` datetime DEFAULT NULL COMMENT '更新时间',PRIMARY KEY (`id`),KEY `sku` (`sku`) USING BTREE) ENGINE=InnoDB AUTO_INCREMENT=217 DEFAULT CHARSET=utf8 COMMENT='京东商品';

代码实现

编写爬虫的业务逻辑

1、使用工具类创建一个HttpClient对象。

2、使用HttpClient发送请求,请求就是搜索的url+页码

3、接收服务端响应html

4、使用Jsoup解析html

5、把解析的商品数据封装成Item对象

6、使用dao把商品写入数据库。

7、需要翻页。

注意:图片也是一个http请求,需要再次发起请求爬取图片,然后存储到本地

@Componentpublic class Crawler {@Autowiredprivate ItemDao itemDao;private String startUrl = "/Search?keyword=手机&wq=手机&s=1&click=1&page=";/*** 爬取页面*/public void doCrawler() {try {//1、使用工具类创建一个HttpClient对象。CloseableHttpClient httpClient = HttpsUtils.getHttpClient();for (int i = 0; i < 10; i++) {//2、使用HttpClient发送请求,请求就是搜索的url+页码HttpGet get = new HttpGet(startUrl + (i * 2 + 1));get.addHeader("User-Agent", " Mozilla/5.0 (Windows NT 6.1; WOW64; rv:64.0) Gecko/0101 Firefox/64.0");CloseableHttpResponse response = httpClient.execute(get);//3、接收服务端响应htmlHttpEntity entity = response.getEntity();String html = EntityUtils.toString(entity, "utf-8");//4、使用Jsoup解析htmlparseHtml(html);//5、把解析的商品数据封装成Item对象//6、使用dao把商品写入数据库。//7、需要翻页。}} catch (Exception e) {e.printStackTrace();}}/*** 页面解析* @param html*/private void parseHtml(String html) throws Exception {//4、使用Jsoup解析htmlDocument document = Jsoup.parse(html);//解析商品列表Elements elements = document.select("li.gl-item");for (Element element : elements) {//解析节点中的商品数据//spuString spu = element.attr("data-spu");//skuString sku = element.attr("data-sku");//titleString title = element.select("div.p-name em").text();//priceString price = element.select("div.p-price i").text();//图片String imgUrl = element.select("div.p-img img").attr("src");String imageName = downloadImage(imgUrl);//商品的urlString itemUrl = element.select("div.p-img > a").attr("href");//5、把解析的商品数据封装成Item对象Item item = new Item();item.setSpu(Long.parseLong(spu));item.setSku(Long.parseLong(sku));item.setTitle(title);if (StringUtils.isNotBlank(price)) {item.setPrice(Float.parseFloat(price));}item.setPic(imageName);item.setUrl(itemUrl);item.setCreated(new Date());item.setUpdated(new Date());//6、使用dao把商品写入数据库。itemDao.save(item);}}/*** 爬取图片* @param imageUrl* @return*/private String downloadImage(String imageUrl) throws Exception {//创建一个HttpClient对象CloseableHttpClient httpClient = HttpsUtils.getHttpClient();//创建一个HttpGet对象HttpGet get = new HttpGet("https:" + imageUrl);get.addHeader("User-Agent", " Mozilla/5.0 (Windows NT 6.1; WOW64; rv:64.0) Gecko/0101 Firefox/64.0");//发送请求CloseableHttpResponse response = httpClient.execute(get);//接收服务端响应的内容。HttpEntity entity = response.getEntity();//需要截取扩展名String extName = imageUrl.substring(imageUrl.lastIndexOf("."));//需要生成文件名。可以使用uuid生成文件名。String fileName = UUID.randomUUID() + extName;//D:\temp\term331\images//创建一个文件输出流,把文件保存到磁盘FileOutputStream outputStream = new FileOutputStream("D:\\temp\\images\\" + fileName);//接收流,把内容保存到磁盘。entity.writeTo(outputStream);//关闭流outputStream.close();//关闭Response对象response.close();return fileName;}}

开启新线程可以让爬取在后台进行,而不是页面一直在转

@RestControllerpublic class CrawlerController {@Autowiredprivate Crawler crawler;@RequestMapping("/start")public String startCrawler() {new Thread(new Runnable() {@Overridepublic void run() {System.out.println("新线程已经启动。。。。。");crawler.doCrawler();}}).start();return "OK";}}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。