事情的起因
前一阵突然收到了这样一封私信
来简书也有一段时间了,这种私信收到了不少,基本都是打着约稿的旗号来骗关注的。其实我觉得主动要求别人的关注没有问题,但是应该明目张胆、大张旗鼓的才对,哪能这样鬼鬼祟祟,企图瞒天过海?看了看这个作者,居然还是个专题编辑呢。
所以我就试探的问问她,既然想约稿,那么到底有没有看过我的文章。
那么现在问题来了,我在简书上也有将近1500个赞了,其中到底有没有这位同志的赞呢?自己手动去看看?这可不是程序员的答案!我们的答案是爬虫!
获取用户timeline
可以很容易的看出,https://www.jianshu.com/users/5aa8494a18c8/timeline 这样的url就是用户的timeline,但是页面默认只展示一部分,更早的timeline是浏览器下拉后获取的。用浏览器的开发者工具可以看到请求信息。
page这个参数显而易见,那么max_id是怎么来的呢?首先要看看这些请求是哪里发出来的。
这个看着信息量好大
再看看s函数,终于找到了max_id的获取方式
max_id可以根据最后一个li元素的id属性获得。
利用requests库进行爬取
requests库就不多介绍了,这里注意两点:
- 要手动设置请求的header,来模拟正常浏览器
- ajax请求要设置额外的header,来模拟下拉刷新
对每次请求下载的response,使用lxml解析,然后利用xpath获取最后一个li元素,进而计算max_id。再用计算出的max_id发起新的请求。
当返回的文本中包含“加入了简书”则停止爬取。
爬取结果分析
爬取了该用户的所有动态,存储到了一个文本文件中,在其中搜索“大神带我来搬砖”,未找到任何结果。所以该用户根本没给我点赞过。
当然,后来我又学会了用 selenium来完成同样的工作。
源码
import requests
from lxml import etree
my_header = "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36"
res = requests.get(url='https://www.jianshu.com/users/5aa8494a18c8/timeline', headers={'user-agent': my_header})
if '大神带我来搬砖' in res.text:
print('found')
page = etree.HTML(res.text)
last_li = page.xpath('''//ul[@class="note-list"]/li[last()]''')[0]
max_id = int(last_li.get('id').split('-')[1]) - 1
file = open("activity.txt",'w',encoding='utf-8')
page = 2
while True:
res = requests.get(url='https://www.jianshu.com/users/5aa8494a18c8/timeline?max_id=%s&page=%s' %(max_id,page),
headers={'user-agent': my_header, 'X-INFINITESCROLL':'true'})
last_li = etree.HTML(res.text).xpath('''/html/body/li[last()]''')[0]
max_id = int(last_li.get('id').split('-')[1]) - 1
page = page + 1
file.write(res.text)
file.write("\n")
if '加入了简书' in res.text:
print('end')
break
file.close()
原文作者:大神带我来搬砖
爱好历史和武侠,专注java、大数据的程序员小哥哥。
学习资料共享,技术问题讨论,希望和大家一起交流进步。