我终于在生活中用到Python了!!!——用爬虫来揭露骗局真相

事情的起因

前一阵突然收到了这样一封私信


6908832-c2c92ddf9022bd80.png
假约稿,真广告

来简书也有一段时间了,这种私信收到了不少,基本都是打着约稿的旗号来骗关注的。其实我觉得主动要求别人的关注没有问题,但是应该明目张胆、大张旗鼓的才对,哪能这样鬼鬼祟祟,企图瞒天过海?看了看这个作者,居然还是个专题编辑呢。


6908832-c47f7abfbfc79f33.png
image.png

所以我就试探的问问她,既然想约稿,那么到底有没有看过我的文章。

6908832-7c34f48ad9bce9bb.png
image.png

那么现在问题来了,我在简书上也有将近1500个赞了,其中到底有没有这位同志的赞呢?自己手动去看看?这可不是程序员的答案!我们的答案是爬虫!

获取用户timeline

可以很容易的看出,https://www.jianshu.com/users/5aa8494a18c8/timeline 这样的url就是用户的timeline,但是页面默认只展示一部分,更早的timeline是浏览器下拉后获取的。用浏览器的开发者工具可以看到请求信息。

6908832-40265bc229da0192.png
动态加载的timeline

page这个参数显而易见,那么max_id是怎么来的呢?首先要看看这些请求是哪里发出来的。

6908832-18d3bf9b15f02261.png
查看请求调用关系

这个看着信息量好大

6908832-34430c42cd3965d3.png
这个函数看着最像

再看看s函数,终于找到了max_id的获取方式


6908832-1d98da22e2b6b1e0.png
max_id

max_id可以根据最后一个li元素的id属性获得。

利用requests库进行爬取

requests库就不多介绍了,这里注意两点:

  1. 要手动设置请求的header,来模拟正常浏览器
  2. ajax请求要设置额外的header,来模拟下拉刷新

对每次请求下载的response,使用lxml解析,然后利用xpath获取最后一个li元素,进而计算max_id。再用计算出的max_id发起新的请求。

当返回的文本中包含“加入了简书”则停止爬取。

爬取结果分析

爬取了该用户的所有动态,存储到了一个文本文件中,在其中搜索“大神带我来搬砖”,未找到任何结果。所以该用户根本没给我点赞过。

6908832-dedc5c1143b67d7b.png
image.png

当然,后来我又学会了用 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、大数据的程序员小哥哥。
学习资料共享,技术问题讨论,希望和大家一起交流进步。

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值