设为首页收藏本站

EPS数据狗论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 2000|回复: 0

用NodeJS爬取知乎的关系链

[复制链接]

171

主题

398

金钱

605

积分

初级用户

发表于 2016-6-23 15:50:11 | 显示全部楼层 |阅读模式
来源:http://www.open-open.com/lib/view/open1458955513605.html

一、介绍
NodeJS单线程、事件驱动的特性可以在单台机器上实现极大的吞吐量,非常适合写网络爬虫这种资源密集型的程序。
这段时间写了一个可以爬取知乎关系链的小爬虫,输入某个用户的用户主页URL,就可以爬取他的关系链:
https://github.com/starkwang/Zhihu-Spider

二、爬虫的实现
数据请求方面使用了request这个模块,用express响应请求,前端构图使用了Echarts,中间数据交互是用websocket做的。
主要用到了知乎的两个API:
//获取目标用户的关注者POST https://www.zhihu.com/node/ProfileFollowersListV2参数:method:"next", //填入next即可params:{    offset:40, //20的倍数,从0开始每次拉取20个关注者    order_by:"created", //填入"created"即可    hash_id:"d965f32a168564f9e58ad3a48a1585a4" //目标用户在知乎唯一的hash_id}, _xsrf:"289c6ef5534d3dbb6a54057826864799" //xsrf参数,cookie中给定的//获取目标用户关注的人POST https://www.zhihu.com/node/ProfileFolloweesListV2参数:method:"next", //填入next即可params:{    offset:40, //20的倍数,从0开始每次拉取20个关注的人    order_by:"created", //填入"created"即可    hash_id:"d965f32a168564f9e58ad3a48a1585a4" //目标用户在知乎唯一的hash_id}, _xsrf:"289c6ef5534d3dbb6a54057826864799" //xsrf参数,cookie中给定的爬虫的工作流程如下:
  • 获取目标用户的关注者、关注的人列表,找出和他相互关注的人(即朋友)
  • 对朋友列表里的朋友重复1中的步骤,找出朋友的朋友列表
  • 遍历2中的结果,找出朋友之间的相互关注关系

三、部分代码
首先我们写一个getUser方法,它的作用是请求一个用户主页URL,获取请求结果,解析出用户的昵称、hash_id、关注者数量、关注的人数量。
var request = require('request');var Promise = require('bluebird');var config = require('../config');function getUser(userPageUrl) {    return new Promise(function(resolve, reject) {        request({            method: 'GET',            url: userPageUrl,            headers: {                'cookie': config.cookie            }        }, function(err, res, body) {            if (err) {                reject(err);            } else {                resolve(parse(body));            }        })    });}function parse(html) {    var user = {};    var reg1 = /data-name=\"current_people\">\[.*\"(\S*)\"\]<\/script>/g;    reg1.exec(html);    user.hash_id = RegExp.$1;    var reg2 = /关注了<\/span><br \/>\n<strong>(\d*)/g;    reg2.exec(html);    user.followeeAmount = parseInt(RegExp.$1);    var reg3 = /关注者<\/span><br \/>\n<strong>(\d*)/g;    reg3.exec(html);    user.followerAmount = parseInt(RegExp.$1);    var reg4 = /<title> (.*) - 知乎<\/title>/g    reg4.exec(html);    user.name = RegExp.$1;    return user;}module.exports = getUser;接下来需要一个fetchFollwerOrFollwee方法,它的作用是输入上面的user对象,根据在第二部分介绍的API,抓取出用户的所有关注的人或者关注者,使用方法类似(使用es6):
getUser('someURL')    .then(user => fetchFollwerOrFollwee({user: user, isFollowees: false})    .then(list => console.log(list))具体代码参照这里,就不贴上来了
接下来要做的就是组合getUser和fetchFollwerOrFollwee,变成一个getFriends方法,输入是用户页URL,输出是用户的好友列表,大概像这样:
function getFriends(someURL){    getUser(someURL)        .then(user => fetchFollwerOrFollwee(...))        .then((followersList, follweesList) => findFriends(followersList, follweesList))}然后我们可以封装一个最后的searchSameFriend方法,输入是某个user和一个好友列表myFriends,输出是这个user的所有好友中,也在列表myFriends中的好友
function searchSameFriend(user, myFriends){    return getFriends(user.url)        .then(user => findSameFriends(userFriends, myFriends))        .then(sameFriends => console.log(sameFriends))}最后整个爬虫的promise流程大概是这样的:
function Spider(){    return getUser(URL)        .then(user => getFriends(user))        .then(userFriends =>             Promise.map(userFriends, friend => searchSameFriend(friend,userFriends))        )}当然其中缺少了部分用websocket和前端数据交互的代码
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关闭

站长推荐上一条 /1 下一条

客服中心
关闭
在线时间:
周一~周五
8:30-17:30
QQ群:
653541906
联系电话:
010-85786021-8017
在线咨询
客服中心

意见反馈|网站地图|手机版|小黑屋|EPS数据狗论坛 ( 京ICP备09019565号-3 )   

Powered by BFIT! X3.4

© 2008-2028 BFIT Inc.

快速回复 返回顶部 返回列表