使用 Python 抓取知乎美图(文末含福利)知乎钓鱼贴汇总

2023-10-09 06:10

本文主要是介绍使用 Python 抓取知乎美图(文末含福利)知乎钓鱼贴汇总,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

福利

当我们爬虫写好,入库,并成功展示出来,不知不觉就实现了一个小程序项目:宅宅生活收藏夹

微信搜索小程序:宅宅生活收藏夹。欢迎大家使用。
在这里插入图片描述
在这里插入图片描述

之前写到宅宅生活收藏夹的部署方法,见 使用Flask,Nginx,
Gunicorn,Supervisor完成网站部署。这次介绍一下如何抓取知乎答案,获取知乎美图。

本文除 Python 相关库的使用外,还会涉及到 mongo 数据库的使用。

因为宅宅生活收藏夹只是为了收集知乎钓鱼贴的图片,有针对性,所以不能通过获取知乎首页列表全面抓取。当然抓取方式大同小异,把抓取列表改为知乎首页也是可以的。

整体思路

首先我们需要收集知乎各类钓鱼贴,这一步可以使用爬虫(通过爬取别人已经收集的钓鱼贴,或者各种社区可能已有钓鱼贴专栏等)获取,也可以在浏览知乎时,发现合适的贴子手动添加。

我们需要将钓鱼贴的 ID 存入数据库中,爬虫运行时读库获取需要爬取的目标贴。

通过写一个爬虫,生成任务池多线程调用。将获取到的答案数据清洗,只收集答案中的图片。

存入库中的结构和知乎的类似:答案集合保存所有答案,每一个答案是一条独立的文档。可能写的有点绕。

具体结构类似这种结构:

{"Answer": [{"id": 1,"question_id": "xxx","title": "xxx","author": "xxx","content: ["imgUrl","..."]},{"id": 2,"question_id": "xxx","title": "xxx","author": "xxx","content: ["imgUrl","..."]},...]
}

其中 Answer 为数据库的集合,集合中的每一项是一条回答。

用这种格式保存的好处是我们只需通过贴子的 ID 查询答案即可,保存起来也非常方便。

知乎爬虫

开始之前

在开始之前需要安装项目依赖,只用到两个常用库:

python3 -m pip install requests pymongo

分别用来爬虫和操作数据库。

安装完成后记得启动 mongo 服务。

Spider

爬虫代码比较简单,代码不过百行,关键找到知乎答案的接口,解析即可。而且这个接口也是非常好找的。

用 Chrome 的开发者工具一下就找到了…

[外链图片转存失败(img-waDRfOCu-1562419272787)(https://user-images.githubusercontent.com/25655581/60421921-64c30d80-9c1d-11e9-9c45-7e4cdbe1b38a.png)]

而且接口也没有任何加密或权限限制,在请求头中加入 Cookies 就可以了。是不是突然觉得很简单?

只要我们控制好频率,不要影响到知乎服务就行了。毕竟我们只是想获取答案而已,不想做其他的。

通过 Chrome 开发者工具分析,请求携带了如下参数,我们只用到 limitoffset,用来控制接口返回的数量和返回的位置。

include: data[*].is_normal,admin_closed_comment,reward_info,is_collapsed,annotation_action,annotation_detail,collapse_reason,is_sticky,collapsed_by,suggest_edit,comment_count,can_comment,content,editable_content,voteup_count,reshipment_settings,comment_permission,created_time,updated_time,review_info,relevant_info,question,excerpt,relationship.is_authorized,is_author,voting,is_thanked,is_nothelp,is_labeled,is_recognized,paid_info;data[*].mark_infos[*].url;data[*].author.follower_count,badge[*].topics
offset:
limit: 3
sort_by: default
platform: desktop

完整的请求 URL 是:

https://www.zhihu.com/api/v4/questions/21115811/answers?include=data%5B*%5D.is_normal%2Cadmin_closed_comment%2Creward_info%2Cis_collapsed%2Cannotation_action%2Cannotation_detail%2Ccollapse_reason%2Cis_sticky%2Ccollapsed_by%2Csuggest_edit%2Ccomment_count%2Ccan_comment%2Ccontent%2Ceditable_content%2Cvoteup_count%2Creshipment_settings%2Ccomment_permission%2Ccreated_time%2Cupdated_time%2Creview_info%2Crelevant_info%2Cquestion%2Cexcerpt%2Crelationship.is_authorized%2Cis_author%2Cvoting%2Cis_thanked%2Cis_nothelp%2Cis_labeled%2Cis_recognized%2Cpaid_info%3Bdata%5B*%5D.mark_infos%5B*%5D.url%3Bdata%5B*%5D.author.follower_count%2Cbadge%5B*%5D.topics&offset=&limit=3&sort_by=default&platform=desktop

我们只要动态更改其中的 questionlimitoffset 就可以了。

我们通过接口返回的答案总数,判断需要翻多少页,当然也可以通过接口返回的 nextprevious 来获取下一页或前一页答案链接。知乎的接口设计的非常方便啊。

当然在翻页抓取的时候切记设置睡眠时间,放在服务器上爬的慢一点也没关系。不要影响到知乎的正常服务

请求成功后我们就可以根据自己的需求,存储数据了,至于如何判断答案中是否有图片,可以参考以下代码。

使用到了 lxml,也可以使用 re 库代替。

@staticmethod
def parse_content(self, content):"""解析答案中的 content,直接获取图片"""if "<img " in content:img_list = set(etree.HTML(content).xpath("//img/@data-original"))return list(img_list)else:return []

先判断回答中是否有 img 标签,如果没有直接返回空列表,如果有的话,通过 data-original 属性获取原始大小的图片链接。也是返回列表类型。

在入库的时候,我们通过 parse_content 的返回判断是否需要入库,如果是 [] 就跳过,如果列表不为空就入库。这样在之后展示的时候不会只展示作者信息,却没有回答的情况了(其实是该作者回答中没有图片)。

调用爬虫

当我们完成上述操作,就可以单独写一个文件使用多线程调用爬虫了。

from concurrent.futures import ThreadPoolExecutorqid_list = db.get_all_question()
crawler_list = [ZhihuSpider(qid).run for qid in qid_list]with ThreadPoolExecutor(max_workers=4) as executor:future = [executor.submit(task) for task in crawler_list]for f in future:f.result()

qid_list 来自查库获取所有的知乎贴子 ID。

使用 concurrent.futures 库并行执行任务,在我们的代码里使用 ThreadPoolExecutor,它使用线程池来异步执行调用。

max_workers 控制最多线程的使用,本例中使用最多4个线程执行任务。

具体文档见 ThreadPoolExecutor,是对 thread 库的封装,让我们使用线程时更加简单。

这篇关于使用 Python 抓取知乎美图(文末含福利)知乎钓鱼贴汇总的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/170881

相关文章

Python列表去重的4种核心方法与实战指南详解

《Python列表去重的4种核心方法与实战指南详解》在Python开发中,处理列表数据时经常需要去除重复元素,本文将详细介绍4种最实用的列表去重方法,有需要的小伙伴可以根据自己的需要进行选择... 目录方法1:集合(set)去重法(最快速)方法2:顺序遍历法(保持顺序)方法3:副本删除法(原地修改)方法4:

Python运行中频繁出现Restart提示的解决办法

《Python运行中频繁出现Restart提示的解决办法》在编程的世界里,遇到各种奇怪的问题是家常便饭,但是,当你的Python程序在运行过程中频繁出现“Restart”提示时,这可能不仅仅是令人头疼... 目录问题描述代码示例无限循环递归调用内存泄漏解决方案1. 检查代码逻辑无限循环递归调用内存泄漏2.

Python中判断对象是否为空的方法

《Python中判断对象是否为空的方法》在Python开发中,判断对象是否为“空”是高频操作,但看似简单的需求却暗藏玄机,从None到空容器,从零值到自定义对象的“假值”状态,不同场景下的“空”需要精... 目录一、python中的“空”值体系二、精准判定方法对比三、常见误区解析四、进阶处理技巧五、性能优化

使用Python构建一个Hexo博客发布工具

《使用Python构建一个Hexo博客发布工具》虽然Hexo的命令行工具非常强大,但对于日常的博客撰写和发布过程,我总觉得缺少一个直观的图形界面来简化操作,下面我们就来看看如何使用Python构建一个... 目录引言Hexo博客系统简介设计需求技术选择代码实现主框架界面设计核心功能实现1. 发布文章2. 加

python logging模块详解及其日志定时清理方式

《pythonlogging模块详解及其日志定时清理方式》:本文主要介绍pythonlogging模块详解及其日志定时清理方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地... 目录python logging模块及日志定时清理1.创建logger对象2.logging.basicCo

Python如何自动生成环境依赖包requirements

《Python如何自动生成环境依赖包requirements》:本文主要介绍Python如何自动生成环境依赖包requirements问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑... 目录生成当前 python 环境 安装的所有依赖包1、命令2、常见问题只生成当前 项目 的所有依赖包1、

如何将Python彻底卸载的三种方法

《如何将Python彻底卸载的三种方法》通常我们在一些软件的使用上有碰壁,第一反应就是卸载重装,所以有小伙伴就问我Python怎么卸载才能彻底卸载干净,今天这篇文章,小编就来教大家如何彻底卸载Pyth... 目录软件卸载①方法:②方法:③方法:清理相关文件夹软件卸载①方法:首先,在安装python时,下

python uv包管理小结

《pythonuv包管理小结》uv是一个高性能的Python包管理工具,它不仅能够高效地处理包管理和依赖解析,还提供了对Python版本管理的支持,本文主要介绍了pythonuv包管理小结,具有一... 目录安装 uv使用 uv 管理 python 版本安装指定版本的 Python查看已安装的 Python

shell编程之函数与数组的使用详解

《shell编程之函数与数组的使用详解》:本文主要介绍shell编程之函数与数组的使用,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录shell函数函数的用法俩个数求和系统资源监控并报警函数函数变量的作用范围函数的参数递归函数shell数组获取数组的长度读取某下的

使用Python开发一个带EPUB转换功能的Markdown编辑器

《使用Python开发一个带EPUB转换功能的Markdown编辑器》Markdown因其简单易用和强大的格式支持,成为了写作者、开发者及内容创作者的首选格式,本文将通过Python开发一个Markd... 目录应用概览代码结构与核心组件1. 初始化与布局 (__init__)2. 工具栏 (setup_t