本文为「大型网红记录片」python 文科数据分析系列。发表于我的博客:
https://willisfusu.github.io/post/jin-ri-tou-tiao-1/
因为老婆博士专业的原因,她需要获取不少网站的新闻或者帖子的评论,并且对评论进行数据分析或者是自然语义分析(NLP)。因此从来没有接触过 python,只有 VB 二级的我自然就成了她的技术支持,为她提供 python 爬虫和数据分析业务 。经过一段时间学习之后,我意识到,这些需求可能在文科的数据分析中具有某种程度上的一致性,如果能够记录下每个项目,可以供他人参考,也可以提高自己对于代码的理解。
结合我自己的学习过程,我觉得如果能够在学习一门编程语言的过程中有一个比较明确的目的,并且从一个可以执行的项目开始,可以大幅度地提高自己的学习意愿与动力。所以我觉得如果可以,尽量从一个简单易行的项目入手,而不是拿到一个事无巨细的教程,从基础开始学习。自下而上是可以打下坚实的基础,但是自上而下的学习可以提供更强大的学习动力。
此篇文章产生的需求为:对指定的今日头条上的新闻,获取文章下面的评论,并且将评论翻译为英文。
我们先随意选定一条新闻,打开新闻页面。比如这条新闻。打开之后页面如下:
然后在页面上右键,选择「检查」
之后会打开开发者工具页面,在 Chrome 下,应该是下面这张图这样
选择 Network, 并且刷新页面
这个时候会得到这个页面所有的网络流量内容,我需要的评论内容肯定也在其中。从评论中随便找一句话,或者一个词,在开发者工具中 Control+F,可以打开搜索。搜索刚才随便找的词句。我就随意选了「转发了」,回车执行搜索后,会发现有结果出现。下一步就是点击搜索结果。点了之后,该搜索结果所在的条目,会变暗(或者变色)。双击刚刚变色的条目,会打开下面的结果
选择 Preview 可以看到预览,看结构应该是一个 Json 文件。选择 data 打开,发现果然就是需要的评论内容。接下来就是 找到请求的 url 地址以及请求的参数信息。点击 headers,查找请求信息
从这张图里,可以知道请求的 url 地址,以及请求方法是 Get 方法。继续往下拉,可以看到请求的信息(request headers)
通过上面五步,就完成了对目标页面的分析,那得到了什么结果呢?请求地址 请求方法 请求参数 Parameters :
通过对目标页面分析之后,得到了请求的地址及请求参数。在使用爬虫时,我们需要自己构造请求链接,所以首先得搞清楚请求链接是怎么构造的。
观察这个链接:
https://www.toutiao.com/article/v2/tab_comments/?aid=24&app_name=toutiao-web&group_id=6829669065624125959&item_id=6829669065624125959&offset=0&count=5
前半部分 可以不用管,后半部分则是请求参数组合在一起。这样看起来,我们只需要在 for 循环中 offset 偏移就可以获取所有的评论。
验证 点击下图中标志出来的图标,清空 network 标签,然后点击评论下面的 「加载更多评论」,看看会返回什么结果。
跟上面一样,找到返回的评论,点击 headers,观察请求地址
将两次请求的地址放到一起对比,更容易找到变化:
由于此次返回的结果直接就是 Json 格式,对于结果处理是相当友好。 代码中用到的库如下:
requests http 请求库,用于向服务器发送请求,获得请求结果。pymongo 数据库,用于数据持久化 (用其它文件存储方式也可以,我这里使用 pymongo 主要是因为自己想要熟练一下这个库的使用。完全也可以用 pandas 或者 Excel 相关的库替代)json json 处理 因为返回的结果是 json 格式。请求链接构造
首先我们要做的是构造请求的 url 链接,根据我们上面的分析,只要在 for 循环中更新 offset 就可以了。代码示例如下:
然后我们再构造结果请求函数
处理返回结果的函数
我们现在构造一个处理返回结果的函数,并且在这个函数里,调用上面的 请求函数。
另外,这一步里需要我们对请求返回的 json 数据的结构进行分析,以便我们可以找到对应的键值对。分析 json 很简单,找一个 json 解析的网页,比如这一个我常用的。 然后将我们上面得到的 json 结果 复制进这个网页中,就可以在右边得到结构比较清晰的结果。
多线程、协程的使用
这个例子中,我其实尝试使用过多线程,毕竟可以大幅度缩减时间。但是今日头条对于爬虫限制的挺厉害,我有一天晚上就被限制了 ip,导致几个小时没法访问今日头条。所以后来就干脆不使用多线程了,能稳定的运行实在是优先于时间少。 也有可能是我使用方法不对,想尝试的朋友可以尝试。pymongo 的使用
在这个例子中使用 pymongo 仅仅是因为我想要练习使用这个工具,数据的持久化有太多方法,使用任何一种即可。其实使用 pymongo 后面还给我带来了不少不便利。获取所有评论的方法
在这个例子中,获取所有评论的方法显得有些「暴力」直接是使用一个很大的数值来代替真实的评论总数。其实这也是无奈,因为头条将对已有评论的回复也计算在评论数中,所以就算是使用真实的评论数,也得对返回的 json→ data 长度进行判断。既然是这样,直接使用一个大数值代替也是一样的。头条新闻评论的获取就到这里了。其实大部分的爬虫都是这样的思路,最重要的就是获得请求地址,以及能构造出正确的请求 url。其实我自己在写的过程中,也是不断去确认一些函数、库、方法的使用详解。比如 json 的 load 与 loads 区别。所以我在这里把一些我查过的列出来,这样也方便我自己回来复习。range()JSONjson.loads