用Java实现网络爬虫三之开始爬取

下面的代码用于爬取知乎推荐页面的所有问题、问题描述、地址、回答内容,爬取地址为http://www.zhihu.com/explore/recommendations

项目源代码见我github上的project

代码介绍

1.新建Zhihu.java类,它是一个JavaBean类,用于封装我们需要得到的内容。代码如下:

2.新建Spider.java类包括两个方法:

  • String sendGet(String url):用于获取网页源码。

打印出result可以得到网页的源码,会看到下面这一串串代码:

找到我们需要爬取的标题那一块,可以看到:

href=””中的内容即是标题的地址链接,而中的内容即是我们需要的标题。那我们该如何使用正则表达式爬取到这些内容呢?标题可以使用"question_link.+?>(.+?)<"来匹配得到,而链接可以使用"<h2>.+?question_link.+?href=\"(.+?)\".+?</h2>"来匹配得到。下面我们就来看看Spide.java中的第二个方法,如何匹配我们我们的内容。

  • ArrayList regexString(String targetStr,String regex):用于将正则表达式和网页源码进行匹配,将得到的内容封装到Zhihu对象中,然后将对象加入到集合lists中,返回集合。

最后我们只需要定义一个测试类,先调用Spider的sendGet(String url)方法中传入目标网页url并得到返回的网页源码,然后调用Spider的regexString(String target)方法得到返回的Zhihu对象的集合,然后将这些内容打印出来,即可看到我们爬取到的内容。

测试类:

打印出的内容:

这样我们便实现了从一个页面上爬取到我们所需信息的网络爬虫。如何进阶呢?

问题分析:

  • 1.从打印台的信息我们可以发现,我们爬取到的问题地址链接并不是属于问题的地址链接,而是属于回答的地址链接,那么这里我们就需要截掉链接后半部分的”/answer/数字”部分。

    解决方法如下:对爬取到的链接采取二次正则表达式的方法进行再一次匹配,需要匹配的字符串即为/question/数字部分,这样我们就将链接作为目标字符串,将该数字部分作为正则表达式即可。代码如下:

    在Zhihu.java文件下添加方法:
    boolean getRealUrl(String url)
    {
        String regex="question/(.+?)/";
        Pattern pattern=Pattern.compile(regex);
        Matcher matcher=pattern.matcher(url);
            while (matcher.find())
            {
                zhihuUrl="http://www.zhihu.com/question/"+matcher.group(1);
                return true;
            }
        return false;
    }
    
  • 2.我们爬取的只是一个页面的相关内容,并没有发挥爬虫的真正强大之处。所以接下来我们就将从该页面爬取到的链接作为二次起始链接。只需在Zhihu.java的构造函数里添加如下方法即可:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    if (getRealUrl(url))
    {
    System.out.println("正在抓取链接"+zhihuUrl);

    String content=Spider.sendGet(zhihuUrl);

    Pattern pattern;
    Matcher matcher;

    pattern=Pattern.compile("zh-question-title.+?<h2.+?>(.+?)</h2>");
    matcher=pattern.matcher(content);
    if (matcher.find()) {
    title = matcher.group(1);
    }

    pattern=Pattern.compile("zh-question-detail.+?<div.+?>(.*?)</div>");
    matcher=pattern.matcher(content);
    if (matcher.find()) {
    titleDescription=matcher.group(1);
    }

    pattern=Pattern.compile("/answer/content.+?<div.+?>(.*?)</div>");
    matcher=pattern.matcher(content);
    while (matcher.find())
    {
    answers.add(matcher.group(1));
    }

    }

这样当我们在Spider类的regexString()方法里,每当用构造方法创建一个Zhihu对象时就会执行上述代码生成从一个链接爬取到的文章标题、内容、标题描述即回答内容并封装到该Zhihu对象里,然后继续执行Spider后面的代码时将该对象添加至list集合中。

最后打印出的内容如下:

至于抓到的内容如何处理这要看你自己如何利用咯。

项目源代码见我Github,地址为 https://github.com/codingXiaxw/Crawler

2018.3.19更

欢迎加入我的Java交流1群:659957958。

2018.4.21更:如果群1已满或者无法加入,请加Java学习交流2群:305335626

联系

If you have some questions after you see this article,you can tell your doubts in the comments area or you can find some info by clicking these links.

记得扫一扫领一下红包再走哦