前几天在看崔庆才老师的教程,用Scrapy抓知乎用户信息,里面用到了递归。之前我写的爬虫都是将已知的固定数据的网址存到list中,然后遍历list中的网址。这次针对简书,我们使用递归来试一下。
什么是递归
程序(或函数)调用自身的编程技巧称为递归( recursion)。一个过程或函数在其定义或说明中有直接或间接调用自身的一种方法,它通常把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解。
递归的优点
1、降低问题难度
2、大大地减少了程序的代码量
3、递归的能力在于用有限的语句来定义对象的无限集合
本案例
如果看图麻烦,可先看大邓录制的视频讲解,请点击链接
【python爬虫】之如何抓取高质量简书用户 - 腾讯视频
(请允许我放个广告)


本案例要抓简书高质量用户的信息,如昵称、id、文章数、文集数、文字数、获得的喜欢等。我们只抓一个用户ta所关注的人,至于这个ta的粉丝,我们不抓。相对而言,ta所关注的人比ta的粉丝要质量高端大气上档次些。
1、先从初始用户,如邓旭东HIT所关注的用户列表开始,获得邓旭东所关注的A、B、C等25个用户。
2、再依次抓这25个用户所关注的用户
3、循环前两步
下面我们先分析网址结构
网址url分析
我们发现,当我向下滚动关注列表时,网页下方会加载,且在图左下角会多出
following?page=3和following?page=4两个xhr类型文件。

将鼠标放置于following?page=3文件上方,悬浮弹出一个网址
http://www.jianshu.com/users/1562c7f16a04/following?page=3


那么问题来了,page这个数字如何构建呢?
我们发现 用户的关注人数除以10,然后取整数再加1就是page的最大数。
比如邓旭东关注了25个人,那么就有page=1,page=2,page=3三个page
现在我们已经构建好了
网址有了,下面开始分析要抓的数据存放在网页源码的什么位置呢?
网页分析
首先我们要先定位多个关注用户的标签,如下图。我们要找到
且该ul标签的属性是user-list。

接下来我们要定位每个用户的数据位置。属性值为info的div标签如下如图

网页解析
用户列表数据的ul标签我们使用BeautifulSoup进行定位。返回用户列表ul标签及其子孙标签
url = 'http://www.jianshu.com/users/1562c7f16a04/following?page=1'
res = requests.get(url)
bsObj = BeautifulSoup(resp, 'lxml')
user_List_Container = bsObj.findAll('ul', {'class': 'user-list'})[0]
user_List = user_List_Container.contents
user_List = [str(user) for user in user_List if user != '\n']
单个用户数据的div标签我们使用re正则表达匹配出其中的数据。
代码排版有点乱,请看知乎文章
源码请 关注公众号: 大邓带你玩转python
网友评论