详细教程 :crawler4j 爬取京东商品信息 Java爬虫入门 crawler4j教程

现今比较流行的爬虫语言,属Java、paython和c语言,笔者学习的是Java语言,所以介绍下使用Java如何爬取网页信息。

我们先从一个最原始的Java爬虫demo开始,再来看如何使用crawler4j这个框架进行爬虫。

Demo

使用Java的Url对象,指向网址并建立连接,获取输入流,解析流中的信息。该Demo只需一个jdk即可,不用引入其他jar包,下面请看源码。

public static void main(String[] args) throws IOException {

        //新建一个url对象 通过构造方法传入url值
        URL url = new URL("https://www.jd.com/");
        //建立Java和url的一个连接,相当于我们访问网址,不同的是Java返回的是connection 我们肉眼返回的是网页内容
        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
        //通过相应状态码判断是否访问成功
        int code = connection.getResponseCode();
        if (code != 200) {
            return;
        }
        //获取connection对网页访问之后 的一个输入流,该流中包含了网页的信息内容
        InputStream stream = connection.getInputStream();
        //通过BufferedReader 获取流中的信息
        BufferedReader reader = new BufferedReader(new InputStreamReader(stream, "utf-8"));
        //输出信息
        String r = null;
        while ((r = reader.readLine()) != null) {
            System.out.println(r);
        }
    }

这里的url传入时必须要带http协议,不能只传入jd.com,否则会报异常:

Exception in thread "main" java.net.MalformedURLException: no protocol: jd.com

我们看一下输出内容(仅截取了一小部分内容):

<!DOCTYPE HTML>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <title>京东(JD.COM)-正品低价、品质保障、配送及时、轻松购物!</title>
  <meta name="description" content="京东JD.COM-专业的综合网上购物商城,销售家电、数码通讯、电脑、家居百货、服装服饰、母婴、图书、食品等数万个品牌优质商品.便捷、诚信的服务,为您提供愉悦的网上购物体验!" />
  <meta name="Keywords" content="网上购物,网上商城,手机,笔记本,电脑,MP3,CD,VCD,DV,相机,数码,配件,手表,存储卡,京东" />
  <script type="text/javascript">
    window.pageConfig = {
      compatible: true,
      preload: false,
      navId: "jdhome2016",
	  timestamp: 1521683291000, 
      isEnablePDBP: 0,,
		surveyTitle : "调查问卷",
		surveyLink : "//surveys.jd.com/index.php?r=survey/index/sid/889711/newtest/Y/lang/zh-Hans",
		leftCateABtestSwitch : 0,
		"" : ""
    };

至此,一个简单的爬虫就已经实现完成了。原理很简单:使用Url对象,指向网址并建立连接,获取输入流,解析流中的信息,根据获取的信息内容,筛选出自己的需求信息即可。当然,这几行代码可能远远不能满足我们的需求,所以市场上有了很多开源的Java爬虫框架,例如nutch、Heritrixcrawler4j等等,具体有何区别,请点击这里。

下面我们进入正题,如何运用crawler4j进行快速爬虫。github源码下载



根据github上的源码和readme.md文档,可以很快使用crawler4j进行爬虫。有一定英语基础可以看看readme.md文档

crawler4j is an open source web crawler for Java which provides a simple interface for crawling the Web. Using it, you can setup a multi-threaded web crawler in few minutes.

上面介绍说,crawler4j是一个开源的爬虫框架,可以快速建立一个多线程爬取网站的程序,而且几分钟之内就能完成编码。

第一步:如果读者使用过maven,可以很轻松的使用maven的pom引入即可。

    <repositories>
        <repository>
            <id>onebeartoe</id>
            <name>onebeartoe</name>
            <url>https://repository-onebeartoe.forge.cloudbees.com/snapshot/</url>
        </repository>
    </repositories>
    
    <dependencies>
        <dependency>
            <groupId>edu.uci.ics</groupId>
            <artifactId>crawler4j</artifactId>
            <version>4.4-SNAPSHOT</version>
        </dependency>
    </dependencies>

如果你没有用过maven那么,你需要把源码打成jar包,然后引入jar包,使用即可。

第二步:创建一个crawler类继承WebCrawler ,并重写两个方法,如下:

public class MyCrawler2 extends WebCrawler {
    @Override
    public boolean shouldVisit(Page referringPage, WebURL url) {
        //这个方法的作用是过滤不想访问的url 
        //return false时  url被过滤掉不会被爬取
        return super.shouldVisit(referringPage, url);
    }
    @Override
    public void visit(Page page) {
        //这个方法的作用是当shouldVisit方法返回true时,调用该方法,获取网页内容,已被封装到Page对象中
        super.visit(page);
    }
}

第三步:创建一个controller类(实际任意类都行),创建main方法,根据官方文档,只需修改线程数量和url就行了。该url可以被称为种子,只要传入一个url,crawler4j就会根据url中的内容获取页面中所有的url然后再次爬取,周而复始,但重复的网址不会重复爬取,不会出现死循环。

public class Controller {
    public static void main(String[] args) throws Exception {
        String crawlStorageFolder = "/data/crawl/root";//文件存储位置
        int numberOfCrawlers = 7;//线程数量

        CrawlConfig config = new CrawlConfig();
        config.setCrawlStorageFolder(crawlStorageFolder);//配置对象设置

        PageFetcher pageFetcher = new PageFetcher(config);
        RobotstxtConfig robotstxtConfig = new RobotstxtConfig();
        RobotstxtServer robotstxtServer = new RobotstxtServer(robotstxtConfig, pageFetcher);
        CrawlController controller = new CrawlController(config, pageFetcher, robotstxtServer);//创建

        controller.addSeed("http://www.ics.uci.edu/~lopes/");//传入的url

        controller.start(MyCrawler.class, numberOfCrawlers);//开始执行爬虫
    }
}

启动main方法就可以完成网页的爬取了。

使用maven方式仅仅引入以上的pom文件,会有个问题,启动的时候总是报错,

Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/http/ssl/TrustStrategy
	at com.chenyao.Controller.main(Controller.java:25)
Caused by: java.lang.ClassNotFoundException: org.apache.http.ssl.TrustStrategy 
这个真是百思不得其解,后来网上搜了一下这个错误。导入了两个jar包就可以了,版本一定要高。
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpcore</artifactId>
            <version>4.4</version>
        </dependency>
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpclient</artifactId>
            <version>4.4.1</version>
        </dependency>

下面写一个实例,爬取京东商品信息


1.控制器

public class Controller {
    public static void main(String[] args) throws Exception {
        String crawlStorageFolder = "/data/crawl/root";//文件存储位置
        int numberOfCrawlers = 1;//线程数量

        CrawlConfig config = new CrawlConfig();
        config.setCrawlStorageFolder(crawlStorageFolder);//配置信息设置

        PageFetcher pageFetcher = new PageFetcher(config);
        RobotstxtConfig robotstxtConfig = new RobotstxtConfig();
        RobotstxtServer robotstxtServer = new RobotstxtServer(robotstxtConfig, pageFetcher);
        CrawlController controller = new CrawlController(config, pageFetcher, robotstxtServer);//创建爬虫执行器
 
        controller.addSeed("https://search.jd.com/Search?keyword=笔记本&enc=utf-8&wq=笔记本");//传入种子 要爬取的网址

        controller.start(MyCrawler2.class, numberOfCrawlers);//开始执行爬虫

2.爬虫类,这里的两个实现方法尤为重要,控制器只是一个访问的入口,具体访问规则和访问结果的获取都是在这两个方法中实现。

查看京东关键词搜索之后的html规则,发现商品都在<li>标签中

继续展开<li>标签,看到该商品的具体信息,这里笔者爬取图片连接,其他信息依然可以根据读者需求自定义爬取


public class MyCrawler2 extends WebCrawler {
       //自定义过滤规则
     private final static Pattern FILTERS = Pattern.compile(".*(\\.(css|js|gif|jpg|png|mp3|mp4|zip|gz))$");
    @Override
    public boolean shouldVisit(Page referringPage, WebURL url) {
        String href = url.getURL().toLowerCase();//爬取的网址 转小写
        //这里定义过滤的网址,我的需求是只爬取京东搜索出来的页面中的商品,url需要以https://search.jd.com/search开头
        boolean b =!FILTERS.matcher(href).matches()&&href.startsWith("https://search.jd.com/search");
        return b;
    }

    @Override
    public void visit(Page page) {
        String url = page.getWebURL().getURL();
        System.out.println(url);
        //判断page是否为真正的网页
        if (page.getParseData() instanceof HtmlParseData) {
            HtmlParseData htmlParseData = (HtmlParseData) page.getParseData();
            String html = htmlParseData.getHtml();//页面html内容
            Document doc = Jsoup.parse(html);//采用jsoup解析html,这个大家不会可以简单搜一下

            //使用选择器的时候需要了解网页中的html规则,自己去网页中F12一下,
            Elements elements = doc.select(".gl-item");
            if(elements.size()==0){
                return;
            }
            for (Element element : elements) {
                Elements img = element.select(".err-product");
                if(img!=null){
                       //输出图片链接
                     System.out.println(img.attr("src"));
                    System.out.println(img.attr("data-lazy-img"));
                }
            }
        }
    }

}

看一下运行结果:


not-visiting就是被过滤的url

下面输出的是图片的链接

使用Crawler4j确实很方便。而且有点傻瓜式。读者可以自己试一下爬取网页给自己带来的乐趣

猜你喜欢

转载自blog.csdn.net/YAO_IT/article/details/79649203