用 Python 抓取掘金数据并保存为 CSV

前言

最近在上某网的数据分析课程,其中有一个项目要求用 R 对自选数据集进行分析。在掘金灌水了半年多的我,第一时间就想到了抓掘金数据。我想要看看在掘金,除了文章内容外,还有哪些因素会影响一篇文章的阅读量。

要解答这个疑问,第一步需要做的事情便是拿到掘金的数据并保存为便于 R 使用的 CSV 格式。

查看数据源

从 Chrome 的控制面板- XHR 里可以看到掘金 timeline 的返回。

其中有一条数据的名字是 「get_entry_by_rank」,看名字这应该就是我需要的数据。将 entrylist 中 collectionCount,commentsCount 等与 timeline 显示的值对比,我发现我可以取到以下我觉得有用的数据:

名称对应返回值名称名称对应返回值名称名称对应返回值名称
文章点赞数collectionCount文章评论数commentsCount文章创建时间createdAt
文章所属分类category文章标签tags文章阅读量viewsCount
本文作者分类role本文作者关注数followeesCount本文作者被关注数followersCount
本文作者总分享链接数postedEntriesCount本文作者总发布文章数postedPostsCount本文作者所有文章累计被点赞数totalCollectionsCount

但是有一个我认为很关键的值 —— 作者所有文章被阅读数 —— 没有在 「get_entry_by_rank」 中返回。好在 「get_entry_by_rank」中返回了作者 ID,我们可以通过这个 ID 进入到作者个人页面 —— juejin.im/user/{ID} ,从而获取与文章作者有关的信息。在作者个人页面的返回数据中,我又找到了以下维度的数据:

名称对应返回值名称名称对应返回值名称名称对应返回值名称
账号创建时间createdAt所有文章被阅读数totalViewsCount所有文章被评论数totalCommentsCount

从数据源获取数据

经过以上查找和对比,我确定了我需要掘金的两条 XHR 返回:

  1. juejin.im/timeline 返回的 「get_entry_by_rank」
  2. juejin.im/user/{ID} 返回的 「get_multi_user」

我决定用 Python 库 Requsts 来自动化获取以上返回。

Requests: 让 HTTP 服务人类

使用 Requests 发送网络请求时需要先构造一个请求头,还需要传入 URL 以及 URL 参数。

复制 「get_entry_by_rank」 的 requests headers 查看请求头、 URL 及 URL 参数内容。

GET /v1/get_entry_by_rank?src=web&uid=5aae85666fb9a028e33b3b35&device_id=***********&token=**********************&limit=20&category=all&recomment=1 HTTP/1.1
Host: timeline-merger-ms.juejin.im
Connection: keep-alive
Origin: https://juejin.im
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36
Accept: */*
Referer: https://juejin.im/timeline
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9
复制代码

从 requests headers 中可以看到

  • URL :timeline-merger-ms.juejin.im/v1/get_entr…
  • URL 参数:
    {
        "src":"web",
        "uid":"5aae85666fb9a028e33b3b35",
        "device_id":"***********",
        "token":"**********************",
        ...
    }
    复制代码
  • 请求头:
    {
        "user-agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36",
        "origin":"https://juejin.im"
    }
    复制代码

将 URL 参数组装为字典payload赋值给关键字参数params,将请求头组装为字典header赋值给关键字参数headers,与 URL 一并传递 requests.get 方法便可发起一次请求:

r = requests.get(timeline-merger-ms.juejin.im/v1/get_entry_by_rank,params = payload,headers = header)
复制代码

r 即为本次请求的响应,使用 r.text 可以看到相应的内容。

从响应中提取需要的数据

Requests 内置了 JSON 解码器,可以处理 JSON 数据。

r = r.json()
复制代码

可以将响应内容转换为 JSON 对象,然后利用 Python 的 JSON 库

import json
复制代码

即可根据返回值名称提取所需的内容,将提取完的数据赋值给字典 data。

将 Data 保存为 CSV

以前一直是将数据直接保存为 JSON 格式,但是在数据分析中,比较常接触的是 CSV 格式的数据,所以这次我决定将数据直接保存为 CSV 格式。

不知道该怎么手写一个方法将 Data 逐字符写入 CSV 文件, Google 后了解到 Python3 自带的 csv 库专门解决这个问题。

通过 with open 打开一个文件,先写入 csv 文件的 header :

import csv
with open('timelinedatacopy.csv','w',newline= "") as f:
    fieldnames = ['viewsCount','collectionCount','commentsCount','tagsCount','category','entryCreatedAt','followersCount','followeesCount','role','postedPostsCount','postedEntriesCount','totalCommentsCount','totalViewsCount','totalCollectionsCount','authorCreatedAt','username']
    writer = csv.DictWriter(f,fieldnames = fieldnames)
    writer.writeheader()
复制代码

列表 fieldnames 中的值要与 data 中的 key 对应。 csv 文件的 header 写入之后便可以写入 data 了:

with open('timelinedatacopy.csv','a',newline="") as f:
        writer = csv.DictWriter(f,fieldnames = fieldnames)#不可以省略
        writer.writerow(data)
复制代码

通过 csv 库,将 Python 的字典保存为 csv 文件变的异常简单。

其它

如何循环抓取 timeline 数据

掘金 timeline 每一次请求返回20篇文章的数据,第二次发起请求的时候 params 会多一个键 before,该值为上一次请求最后一篇文章的rankIndex,通过 while 循环持续发起请求并且每次请求利用上一次请求的返回的数据更新 before 的值即可。

如何根据 ID 获取每篇文章作者相关信息

每一次 timeline 数据抓取成功后,顺序遍历返回数据,逐条对 「get_multi_user」 发起请求并执行与抓取 timeline 数据一样的流程。

PS

非专门的数据工程师,代码水平献丑,就不放 Github 丢人了。需要参考源码的同学可以私信微博 DataMonologue。单独发你?。

下一篇文章我会写一下如何用 R 对本数据集进行的分析及我的洞见。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值