Webmagic(爬虫)抓取新浪博客案例

JAVA herman 1389浏览 0评论
公告:“业余草”微信公众号提供免费CSDN下载服务(只下Java资源),关注业余草微信公众号,添加作者微信:xttblog,发送下载链接帮助你免费下载!
本博客日IP超过1800,PV 2600 左右,急需赞助商。
极客时间所有课程通过我的二维码购买后返现24元微信红包,请加博主新的微信号:xttblog,之前的微信号好友位已满,备注:返现
所有面试题(java、前端、数据库、springboot等)一网打尽,请关注文末小程序
视频教程免费领

Webmagic框架更偏重实际的内容抓取。今天为大家分享Webmagic 爬虫框架抓取新浪博客的案例。

我们以作者的新浪博客http://blog.sina.com.cn/flashsword20作为例子。在这个例子里,我们要从最终的博客文章页面,抓取博客的标题、内容、日期等信息,也要从列表页抓取博客的链接等信息,从而获取这个博客的所有文章。

列表页的格式是“http://blog.sina.com.cn/s/articlelist_1487828712_0_1.html“, 其中“0_1”中的“1”是可变的页数。

新浪博客列表页

文章页的格式是“http://blog.sina.com.cn/s/blog_58ae76e80100g8au.html”, 其中“58ae76e80100g8au”是可变的字符。

文章页截图

通过上面的分析,我先要找到文章的url,再更加url获取文章。所以如何发现这个博客中所有的文章地址,是爬虫的第一步。

我们可以使用正则表达式http://blog\\.sina\\.com\\.cn/s/blog_\\w+\\.html对URL进行一次粗略过滤。这里比较复杂的是,这个URL过于宽泛,可能会抓取到其他博客的信息,所以我们必须从列表页中指定的区域获取URL。

在这里,我们使用xpath//div[@class=\\”articleList\\”]选中所有区域,再使用links()或者xpath//a/@href获取所有链接,最后再使用正则表达式http://blog\\.sina\\.com\\.cn/s/blog_\\w+\\.html,对URL进行过滤,去掉一些“编辑”或者“更多”之类的链接。于是,我们可以这样写:

page.addTargetRequests(page.getHtml().xpath("//div[@class=\"articleList\"]").links().regex("http://blog\\.sina\\.com\\.cn/s/blog_\\w+\\.html").all());

同时,我们需要把所有找到的列表页也加到待下载的URL中去:

page.addTargetRequests(page.getHtml().links().regex("http://blog\\.sina\\.com\\.cn/s/articlelist_1487828712_0_\\d+\\.html").all());

文章页面信息的抽取是比较简单的,写好对应的xpath抽取表达式就可以了。

page.putField("title", page.getHtml().xpath("//div[@class='articalTitle']/h2"));
page.putField("content", page.getHtml().xpath("//div[@id='articlebody']//div[@class='articalContent']"));
page.putField("date",
        page.getHtml().xpath("//div[@id='articlebody']//span[@class='time SG_txtc']").regex("\\((.*)\\)"));

现在,我们已经定义了对列表和目标页进行处理的方式,现在我们需要在处理时对他们进行区分。在这个例子中,区分方式很简单,因为列表页和目标页在URL格式上是不同的,所以直接用URL区分就可以了!

这个例子完整的代码如下:

package us.codecraft.webmagic.samples;
import us.codecraft.webmagic.Page;
import us.codecraft.webmagic.Site;
import us.codecraft.webmagic.Spider;
import us.codecraft.webmagic.processor.PageProcessor;
public class SinaBlogProcessor implements PageProcessor {
    public static final String URL_LIST = "http://blog\\.sina\\.com\\.cn/s/articlelist_1487828712_0_\\d+\\.html";
    public static final String URL_POST = "http://blog\\.sina\\.com\\.cn/s/blog_\\w+\\.html";
    private Site site = Site
            .me()
            .setDomain("blog.sina.com.cn")
            .setSleepTime(3000)
            .setUserAgent(
                    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_2) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.65 Safari/537.31");
    @Override
    public void process(Page page) {
        //列表页
        if (page.getUrl().regex(URL_LIST).match()) {
            page.addTargetRequests(page.getHtml().xpath("//div[@class=\"articleList\"]").links().regex(URL_POST).all());
            page.addTargetRequests(page.getHtml().links().regex(URL_LIST).all());
            //文章页
        } else {
            page.putField("title", page.getHtml().xpath("//div[@class='articalTitle']/h2"));
            page.putField("content", page.getHtml().xpath("//div[@id='articlebody']//div[@class='articalContent']"));
            page.putField("date",
                    page.getHtml().xpath("//div[@id='articlebody']//span[@class='time SG_txtc']").regex("\\((.*)\\)"));
        }
    }
    @Override
    public Site getSite() {
        return site;
    }
    public static void main(String[] args) {
        Spider.create(new SinaBlogProcessor()).addUrl("http://blog.sina.com.cn/s/articlelist_1487828712_0_1.html")
                .run();
    }
}

通过这个例子我们可以发现主要使用几个方法:

  • 从页面指定位置发现链接,使用正则表达式来过滤链接.
  • 在PageProcessor中处理两种页面,根据页面URL来区分需要如何处理。

如果你觉得用if-else来区分不同处理有些不方便,那么可以使用SubPageProcessor来解决这个问题。

业余草公众号

最后,欢迎关注我的个人微信公众号:业余草(yyucao)!可加QQ1群:135430763(2000人群已满),QQ2群:454796847(已满),QQ3群:187424846(已满)。QQ群进群密码:xttblog,想加微信群的朋友,之前的微信号好友已满,请加博主新的微信号:xttblog,备注:“xttblog”,添加博主微信拉你进群。备注错误不会同意好友申请。再次感谢您的关注!后续有精彩内容会第一时间发给您!原创文章投稿请发送至532009913@qq.com邮箱。商务合作可添加助理微信进行沟通!

本文原文出处:业余草: » Webmagic(爬虫)抓取新浪博客案例