如何在神箭手上快速开发爬虫——第六课 如何爬取分类数据【春雨医生健康资讯文章采集】

1、本课完整的爬虫代码可以在神箭手示例代码中查看
2、如何在神箭手上运行代码,请查看文档
3、更详细的爬虫开发教程,请查看文档  


大家好,我是神箭手的游牧老师~

今天继续给大家带来 如何在神箭手上快速开发爬虫 系列教程的第六课:如何爬取分类数据。

对于基础知识还不熟悉的童鞋,请先从第一课开始学起啊:第一课点这里


神箭手为了简化爬虫代码,默认是全站爬虫,会自动从入口页链接中自动发现新的链接,全站爬取。但是在爬取文章或者商品数据的时候,我们可能需要精准采集,比如只爬取某些分类的文章或者某个店铺某个关键字的商品。对于这种情况,有两种处理办法:

1、优化列表页和内容页url正则表达式,使其只匹配需要的url;

2、关闭自动链接发现,手动添加需要的url到待爬队列中。

第一种办法没什么好说的,大家多熟悉熟悉正则表达式即可。本文主要讲解第二种办法。关闭自动链接发现和手动添加新的链接,都是在网页下载完成后的回调函数中处理的。


举个例子,按分类爬取春雨医生的健康资讯文章:



我们首先通过自定义输入(在本系列上一篇文章有具体讲解如何使用自定义输入),传入要爬取的分类的首页url,比如:https://www.chunyuyisheng.com/pc/health_news/?channel_id=21

// 输入要爬取的分类url,可以输入多个 
var channelUrls = ["https://www.chunyuyisheng.com/pc/health_news/?channel_id=21", "https://www.chunyuyisheng.com/pc/health_news/?channel_id=35"];//@input(channelUrls, 要爬取的资讯分类首页url)

然后在爬取前,将这些首页url添加到入口页url列表中:

configs.initCrawl = function (site) {
  // 分别判断输入的资讯分类首页链接是否正确,正确的话添加到入口页url列表中
  for(var i in channelUrls){
    if(!/https:\/\/www\.chunyuyisheng\.com\/pc\/health_news/.exec(channelUrls[i])){
      console.log("输入的资讯分类首页url:"+channelUrls[i]+"错误!");
    }else{
      site.addScanUrl(channelUrls[i]);
    }
  }
};

在入口页、列表页和内容页下载完成后的回调函数中,返回值改为false表示关闭自动发现新链接,防止处理到其他分类的链接

// 下载完入口页内容的回调
configs.onProcessScanPage = function (page, content, site) {
  // 返回false表示不自动从入口页中发现新链接。因为本代码中入口页也属于列表页,所以在列表页回调中统一处理
  return false;
};
// 下载完内容页内容的回调
configs.onProcessContentPage = function (page, content, site) {
  // 返回false表示不自动从内容页中发现新链接
  return false;
};

同时在列表页的回调函数中,手动添加该页的内容页url和下一页列表页url到待爬队列中

// 下载完列表页内容的回调
configs.onProcessHelperPage = function (page, content, site) {
  // 从列表页中抽取内容页url,添加到待爬url队列中
  var contentUrls = extractList(content, "//ul[contains(@class,'health-news-list')]//a[contains(@class,'title')]/@href");
  for(var i in contentUrls){
    site.addUrl(contentUrls[i]);
  }
  // 从列表页中抽取下一页列表页url,添加到待爬url队列中
  var nextPageUrl = extract(content, "//a[contains(text()[1],'下一页') and not(contains(@class,'disabled'))]/@href");
  if(nextPageUrl){
    site.addUrl(nextPageUrl);
  }
  // 返回false表示不自动从列表页中发现新链接
  return false;
};

列表页是类似这样的url:https://www.chunyuyisheng.com/pc/health_news/?channel_id=21&page=2;内容页是类似这样的url:https://www.chunyuyisheng.com/pc/article/115739/。最后我们在configs里设置好域名、内容页和列表页url正则、从内容页抽取数据的xpath等:

// 定义抽取数据的规则 和 列表页、内容页url正则
var configs = {
  domains: ["chunyuyisheng.com"],
  scanUrls: [],
  contentUrlRegexes: [/https:\/\/www\.chunyuyisheng\.com\/pc\/article\/\d+.*/],
  helperUrlRegexes: [/https:\/\/www\.chunyuyisheng\.com\/pc\/health_news\/\?channel_id=\d+.*/, /https:\/\/www\.chunyuyisheng\.com\/pc\/health_news\/\#channel/],
  fields: [
    {
      name: "article_title",
      alias: "文章标题", 
      selector : "//h1[contains(@class,'news-detail-title')]",
      required: true 
    },
    {
      name: "article_abstract",
      alias: "文章摘要",
      selector: "//p[contains(@class,'desc')]"
    },
    {
      name: "article_content",
      alias: "文章内容",
      selector: "//div[contains(@class,'news-content')]"
    },
    {
      name: "article_publish_time",
      alias: "发布时间",
      selector: "//p[contains(@class,'time')]"
    }, 
    {
      name: "article_category",
      alias: "文章分类",
      selector: "//ul[contains(@class,'bread-crumb')]//li[position()>1 and contains(@class,'item')]/a"
    }
  ]
};

这个按分类爬取文章的爬虫就写好了,是不是真的五分钟搞定!!完整的代码点这里:http://www.shenjian.io/index.php?r=demo/docs&demo_id=500015


把代码拷贝到神箭手上,启动爬虫,爬取结果里就源源不断的出现按分类爬的文章了:


分享到: