如何在神箭手上快速开发爬虫——第七课 如何爬取登录才可见的数据【5sing歌曲信息采集】

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


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

今天继续给大家带来 如何在神箭手上快速开发爬虫 系列教程的第七课:如何爬取登录才可见的数据。

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


今天我们来采集5sing网站的歌曲信息,打开网站:http://5sing.kugou.com/yc/3497845.html。点击”下载”,可以发现,如果要看到歌曲的下载地址,是需要先登录的:



那如何采集歌曲的下载地址数据呢?就需要在开始爬取的时候,先进行模拟登录。先分析登录请求的地址和发送的数据等,然后再在爬虫代码里发送登录请求。

神箭手会自动保存和使用所有请求的cookie,所以只要请求登录成功,就可以正常采集了!


第一步:分析并发送登录请求

使用浏览器的开发者工具,很容易查找到点击登录按钮后发送的请求:



看上去还是比较简单的post请求的,那么我们就很容易写出来登录请求的函数:

// 运行和测试时先输入5sing账号信息,爬虫会自动模拟登录
var username = "*******";//@input(username, 5sing登录账号(歌曲下载地址是登录可见的))
var password = "*******";//@password(password, 5sing登录密码)
/*
  模拟登录的函数,神箭手爬虫会自动保存cookies
*/
function login(site){
  // 登录请求的地址
  var loginUrl = "http://5sing.kugou.com/login/";
  // 请求参数
  var options = {
    method: "post",
    data: {
      RefUrl: "http%3A%2F%2F5sing.kugou.com%2Findex.html",
      txtUserName: username,
      txtPassword: password,
      txtCheckCode: "验证码"
    },
    result: "response" //返回包含状态码等信息的对象。不写这句表示返回请求的html结果
  };
  // 发送登录请求
  var response = site.requestUrl(loginUrl, options);
  // 根据请求返回的状态,判断并返回是否登录成功(51sing登录成功会返回302自动跳转)
  if(response.statusCode == "302"){
    console.log("登录成功!");
    return true;
  }else{
    console.log("登录失败!返回信息:"+JSON.stringify(response));
    return false;
  }
}


第二步:登录成功后,开始爬取

根据login函数的返回,可以判断登录是否成功。

如果成功,就在开始爬取前的initCrawl回调函数里,添加第一页歌曲的url到入口页链接中,爬虫就会自动从第一页开始往后爬取歌曲信息了:

configs.initCrawl = function (site) {
  if(!username || !password){
    system.exit("请先设置5sing的账户名和密码!");
  }else{
    if(login(site)){
      // 添加要爬取的歌曲列表首页url
      site.addScanUrl("http://5sing.kugou.com/yc/list?t=-1");
    }
  }
};


需要注意的是,如果设置了自动接入代理ip,还需要在ip切换后的回调函数onChangeProxy里,重新登录一次:

configs.onChangeProxy = function (site, page) {
  // 如果ip切换了,需要重新登录(如果没有使用代理ip,该函数不会调用)
  login(site);
};


第三步:定义数据抽取规则

和其他爬虫一样,使用xpath抽取详情页的数据,包括歌曲id、名称、音乐人、上传时间等。

需要注意的是,下载地址并不在详情页源码中,需要发送异步请求来抽取这个数据,这里用到了AttachedUrl的数据抽取来源,具体请查阅神箭手爬虫开发接口文档:

var configs = {
    domains: ["5sing.kugou.com"],
    scanUrls: [],
    contentUrlRegexes: [/http:\/\/5sing\.kugou\.com\/yc\/\d+\.html/],
    helperUrlRegexes: [/http:\/\/5sing\.kugou\.com\/yc\/list\?t=-1(.*p=\d+.*)?/],
    interval: 10000,
    fields: [
        {
            name: "sid",
            alias: "歌曲id",
            selector: "//*[@id='func_Down']/@data-songid",
            required: true,
            primaryKey : true // 歌曲id作为去重字段
        },
        {
            name: "name",
            alias: "歌曲名",
            selector: "//div[contains(@class,'view_tit')]/h1",
            required: true 
        },
        {
            name: "singer",
            alias: "音乐人",
            selector: "//h3[contains(@class,'user_name')]/a/text()"
        },
        {
            name: "upload_time",
            alias: "上传时间",
            selector: "//em[contains(text()[1],'上传时间')]/../text()"
        },
        {
            name: "download_settting",
            alias: "下载设置",
            selector: "//em[contains(text()[1],'下载设置')]/../text()"
        },
        {
            name: "download_link",
            alias: "文件下载地址",
            sourceType: SourceType.AttachedUrl, // 通过异步请求抽取数据
            attachedUrl: "http://service.5sing.kugou.com/song/getPermission?songId={sid}&songType=1",
            selectorType: SelectorType.JsonPath,
            selector: "$.data.fileName"
        }
    ]
};


完整的代码请点击此链接查看http://www.shenjian.io/index.php?r=demo/docs&demo_id=500017

把代码拷贝到神箭手上,在爬虫设置里输入账户和密码,点击运行,就能看到爬取的数据啦:


分享到: