Java爬虫入门-基于jsoup采集京东商品数据简单实现

近来,云计算结课要求是要做一个基于Hadoop组件的电商网站数据分析项目;数据分析,数据分析,要先有数据才能分析~数据哪来呢,当然是爬虫。
其中爬虫最热门的语言肯定都是想到Python。但是Java作为我的本命语言,我就尝试了一下Java的爬虫实现,其实,现在Java也有很多框架包对爬虫的支持非常方便。下面,作为爬虫的入门,我用Jsoup来实现一下京东商品数据的采集。

首先,和任何项目前提一样,新建一个项目,配置好依赖。


            org.jsoup
            jsoup
            1.11.3
        
        
        
            junit
            junit
            4.12
            compile
 

上面就先引入jsoup包和测试用的junit包。

在进行爬虫前,要先对目标网站有一定的了解

我这次是需求是对京东商城某个关键词下的商品数据采集

1、打开京东商城
在首页输入一个关键词搜索,观察url的变化
比如:输入 iphone 搜索

Java爬虫入门-基于jsoup采集京东商品数据简单实现_第1张图片
我们可以观察到地址栏有输入的信息,在keyword后面,

可以尝试一下去掉关键词后面的信息再刷新网页
Java爬虫入门-基于jsoup采集京东商品数据简单实现_第2张图片
依然没问题,这时候就可以确定在京东上搜索什么都是由keyword后面的参数决定的。

2、代码实现

确定之后就可以写代码尝试先吧搜索后的一页数据获取到

Jsoup提供的API非常简单,只需要几步就能获取到网页的数据。

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import java.io.IOException;
import java.net.URL;

public class JsoupTest {
    public static void main(String[] args) throws IOException {
        //要爬取的网址
        String url = "https://search.jd.com/Search?keyword=iphone";
        //传进一个URL,和响应超时时间,返回一个类似前端Js的DOM对象
        Document doc = Jsoup.parse(new URL(url),3000);
        //打印DOM对象的html
        System.out.println(doc.html());
        //打印DOM对象的所有text
        System.out.println(doc.text());
    }
}

运行代码
第一个doc.html()打印出了网页源代码的所有标签+文本内容
第二个doc.text()只打印出网页的文本内容。

爬虫的第一小步实现了!可以通过代码访问到了网页

3、提取有效数据

上面得到数据肯定是不符合我们的需求的,爬虫最重要的是洗数据
就是只提取有效的数据

比如说:我只需要商品的标题和价格
Java爬虫入门-基于jsoup采集京东商品数据简单实现_第3张图片
在网页上右击你想要的数据,检查。
Java爬虫入门-基于jsoup采集京东商品数据简单实现_第4张图片
可以确定价格是在p-price的div中,标题是在p-name这个div中。

而每个商品都在J_goodsList这个div里面:
Java爬虫入门-基于jsoup采集京东商品数据简单实现_第5张图片
这时候,就可以用到Jsoup强大的解析功能,和js的用法十分相似。

 Element goodsList = doc.getElementById("J_goodsList");
        //遍历本页所有商品
        Elements items = goodsList.getElementsByClass("gl-item");
        for (Element item : items) {
         //获取商品id
           String id = item.attr("data-sku");
            //获取商品标题
            String pname = item.getElementsByClass("p-name").get(0).getElementsByTag("em").get(0).text();
            System.out.println(pname);
            //获取商品价格
            String price = item.getElementsByClass("p-price").get(0).getElementsByTag("i").get(0).text();
            System.out.println(price);
        }

运行结果:
Java爬虫入门-基于jsoup采集京东商品数据简单实现_第6张图片
4、获取多页数据

前面拿到的都是本页的数据,那么如何获取多页的呢?

在页面中点击下一页,观察url的变化

Java爬虫入门-基于jsoup采集京东商品数据简单实现_第7张图片

发现jd的页面变化参数是奇数变化的,也就是第二页page参数是3,第三页是5…知道规律了还不简单,写个循环搞定。

这时候可以优化一下代码,在url中可以吧keyword和page提出来,这样就
传参数查询所需要的数据。

    private static void findProductByKey(String keyword, Integer page) throws IOException {
        for (Integer integer = 1; integer <= page * 2 - 1; integer += 2) {
            String url = "https://search.jd.com/Search?keyword=" + keyword + "&page=" + integer;
            Document doc = Jsoup.parse(new URL(url), 5000);
            Element goodsList = doc.getElementById("J_goodsList");
            //遍历本页所有商品
            Elements items = goodsList.getElementsByClass("gl-item");
            for (Element item : items) {
                //获取商品标题
                String pname = item.getElementsByClass("p-name").get(0).getElementsByTag("em").get(0).text();
                System.out.println(pname);
                //获取商品价格
                String price = item.getElementsByClass("p-price").get(0).getElementsByTag("i").get(0).text();
                System.out.println(price);
            }
        }
    }

5、获取动态加载的数据

现在很多网站为了加载速度,很多页面上的东西都是通过js或者ajax动态加载出来的,页面的源代码并没有这些数据,而Jsoup获得的DOM对象只能是静态的源码。

比如说我想获取一个商品的评价。
虽然在页面的检查中可以看到有数据,但是这些都是动态加载出来的,
如果你在网页上查看整个页面源代码就发现找不到这些数据。这种情况就不能单纯靠Jsoup获取了。

打开控制台的network,刷新页面,观察数据包
这时候发现productPageComments这个包中有商品评价的数据
Java爬虫入门-基于jsoup采集京东商品数据简单实现_第8张图片
观察这个数据包的请求头信息
在这里插入图片描述
复制请求头的url,这个才是我们需要解析的地址,而且观察多个商品,发现改地址的变化规律只和商品的id和page参数有关,所以我们也可以利用这个拼接字符串循环拿到多条数据。

   /**
     * @param id   商品ID
     * @param page 要拿多少页评价
     * @throws IOException
     */
    private static void getAppraise(String id, int page) throws IOException {
        for (int i = 0; i < page; i++) {
            String url = "https://club.jd.com/comment/productPageComments.action?callback=fetchJSON_comment98&productId=" 
                    + id + "&score=0&sortType=5&page=" + i + "&pageSize=10&isShadowSku=0&fold=1";
            Document parse = Jsoup.parse(new URL(url), 3000);
            System.out.println(parse.html());
            }
        }
    }

到这里离成功还差一点,因为上面请求得到不是我们的html格式的,而是一串Json格式的字符串
Java爬虫入门-基于jsoup采集京东商品数据简单实现_第9张图片
这个问题简单,将Json解析就好了。

我这里采用fastjson进行解析。

首先先添加fastjson的依赖。


            com.alibaba
            fastjson
            1.2.66

要去掉前面的“fetchJSON_comment98(” 和后面的“);”才是符合格式的json数据,可以用字符串工具进行字符串截取。

//截取正确格式的json字符串,进行json解析,转为json对象
 JSONObject jsonObject = JSON.parseObject(parse.text().substring(parse.text().indexOf("(") + 1, parse.text().lastIndexOf(");")));
 //获取评论元素,循环输出
 JSONArray comments = jsonObject.getJSONArray("comments");
            for (Object comment : comments) {
                JSONObject parse1 = (JSONObject) comment;
                System.out.println(parse1.get("content").toString());
                System.out.println("-------------------");
            }

Java爬虫入门-基于jsoup采集京东商品数据简单实现_第10张图片
最后,成功拿到评论数据,接下就可以创建对象,连接数据库等过程将数据持久化操作~
入门成功【滑稽】

你可能感兴趣的:(Java,java,大数据)