python爬虫:将知乎专栏文章转为pdf

欢迎关注本人的知乎主页~

实现思路

  1. 用户输入专栏ID:

    1. 代码首先提示用户输入一个知乎专栏的ID,默认值为 'c_1747690982282477569'
    2. 输入的ID用于构建API请求的URL。
  2. 发送HTTP请求:

    1. 使用 requests.get() 向知乎API发送GET请求,获取指定专栏的文章列表。
    2. 检查响应的状态码,确认请求是否成功。
  3. 如果请求成功,解析返回的JSON数据,并将其保存到本地文件 zhihu.json 中。

  4. 定义处理HTML内容的函数 process_content

    1. 这个函数用于处理文章的HTML内容,具体操作包括:
      1. 移除 data-pid 属性。
      2. 替换特殊的字符 \u003C\u003E<>
      3. 添加段落的缩进和底部边距。
      4. 移除包含 <img><figure> 标签。
      5. 移除 class="ztext-empty-paragraph"<p> 标签。
      6. 去除多余的 <br> 标签。
      7. 确保每个段落都在 <p></p> 之间。
  5. 从之前保存的 zhihu.json 文件中读取JSON数据,并解析为Python字典。

  6. 从解析后的数据中提取文章的具体内容和标题。

  7. 创建一个名为 articles 的目录来保存生成的HTML文件。

  8. 使用 Jinja2 模板引擎初始化模板环境,并加载预定义的HTML模板 template.html

  9. 遍历文章数据并生成HTML文件:

    1. 对每篇文章的内容进行处理,并使用Jinja2模板渲染为完整的HTML页面。
    2. 将渲染后的HTML内容保存到 articles 目录下的 .html 文件中。
  10. 转换HTML文件为PDF文件:

    1. 创建一个名为 pdfs 的目录来保存生成的PDF文件。
    2. 遍历 articles 目录中的所有HTML文件,并使用 pdfkit 将其转换为PDF格式。
    3. 在转换过程中,禁止加载远程资源,并忽略加载错误。
  11. 输出结果信息,告知用户所有文章已保存为HTML文件,并且所有HTML文件已转换为PDF文件。

完整代码

import json
import os
import re
from jinja2 import Environment, FileSystemLoader
import requests
import pdfkit# 用户输入专栏名称,默认为c_1747690982282477569
column_id = input("请输入知乎专栏ID(默认为 c_1747690982282477569):") or 'c_1747690982282477569'
url = f'https://www.zhihu.com/api/v4/columns/{column_id}/articles'# 发送请求获取专栏文章列表
response = requests.get(url)# 检查请求是否成功
if response.status_code == 200:# 解析 JSON 数据data = response.json()# 保存到本地文件output_file = 'zhihu.json'with open(output_file, 'w', encoding='utf-8') as file:json.dump(data, file, ensure_ascii=False, indent=4)print(f"数据已保存到 {output_file}")
else:print(f"请求失败,状态码:{response.status_code}")def process_content(content):"""处理HTML内容,移除不需要的标签和属性,调整样式等。"""# 移除标识符号# 匹配 data-pid 属性,并允许属性值使用普通双引号或转义的双引号,以及可能存在的空白字符content = re.sub(r'data-pid\s*=\s*(?:"|\")(.+?)(?:"|\")', '', content)# 替换特殊字符content = content.replace('\u003C', '<').replace('\u003E', '>')# 处理<p>标签,添加缩进和底部边距content = content.replace('<p ', '<p style="text-indent: 2em; margin-bottom: 1em;">')# 处理</p>标签content = content.replace('</p>', '</p>')# 移除包含 <img> 的 <figure> 标签content = re.sub(r'<figure.*?>.*?</figure>', '', content, flags=re.DOTALL)# 移除 class="ztext-empty-paragraph"content = re.sub(r'<p[^>]*class\s*=\s*["\']ztext-empty-paragraph["\'][^>]*>', '</p>', content)# 去除多余的<br>content = re.sub(r'</p><br>', '</p>', content)# 最后一个段落不应该有额外的换行if content.endswith('<p style="text-indent: 2em; margin-bottom: 1em;">'):content = content[:-len('<p style="text-indent: 2em; margin-bottom: 1em;">')]content += '</p>'# 确保每段文本都包裹在<p>和</p>之间paragraphs = re.split(r'(<p[^>]*>)', content)cleaned_paragraphs = []for i in range(0, len(paragraphs), 2):if i + 1 < len(paragraphs):  # 如果有对应的<p>标签cleaned_paragraphs.append(paragraphs[i])cleaned_paragraphs.append(paragraphs[i + 1].strip())else:cleaned_paragraphs.append(paragraphs[i].strip())content = ''.join(cleaned_paragraphs)return content# 定义输入文件名
input_file = 'zhihu.json'# 从文件中读取JSON数据
with open(input_file, 'r', encoding='utf-8') as file:json_data = file.read()# 解析JSON数据
data = json.loads(json_data)# 提取"data"数组中的内容
articles_data = data['data']# 创建一个目录来保存HTML和PDF文件
output_dir = 'articles'
os.makedirs(output_dir, exist_ok=True)# 初始化Jinja2环境
env = Environment(loader=FileSystemLoader('.'))
template = env.get_template('template.html')# 遍历每一篇文章的数据
for article in articles_data:# 获取文章内容和标题article_id = str(article['id'])content = article['content']processed_content = process_content(content)title = article['title']# 渲染HTML模板html_content = template.render(title=title, content=processed_content)# 移除连续的 '>>',只保留一个 '>'html_content = re.sub(r'(>)>', r'\1', html_content)# 将内容写入HTML文件html_file_path = os.path.join(output_dir, f'{article_id}.html')with open(html_file_path, 'w', encoding='utf-8') as file:file.write(html_content)print("所有文章已保存为HTML文件")# 指定输入文件夹
input_dir = 'articles'# 创建一个目录来保存 PDF 文件
output_dir = 'pdfs'
os.makedirs(output_dir, exist_ok=True)# 遍历文件夹中的所有 HTML 文件
for filename in os.listdir(input_dir):if filename.endswith('.html'):# 获取 HTML 文件的完整路径html_file_path = os.path.join(input_dir, filename)# 构造 PDF 文件的名称pdf_filename = os.path.splitext(filename)[0] + '.pdf'pdf_file_path = os.path.join(output_dir, pdf_filename)# 读取 HTML 文件内容with open(html_file_path, 'r', encoding='utf-8') as file:html_content = file.read()# 将 HTML 文件转换为 PDF 文件try:# 使用 options 禁止加载远程资源options = {'disable-local-file-access': None,'load-error-handling': 'ignore',}# 注意html文件名不能含有中文pdfkit.from_string(html_content, pdf_file_path, options=options)print(f"{filename} 已转换为 {pdf_filename}")except Exception as e:print(f"转换 {filename} 时发生错误:{e}")print("所有 HTML 文件已转换为 PDF 文件。")

运行结果

在这里插入图片描述

待完善的功能

  1. 本项目没有保存知乎文章中的图片,因为图片大小较难以控制;
  2. 知乎文章中的引用和脚注没能很好地处理。

以上问题有待解决。另外,这篇文章介绍了直接保存知乎网页文章的方法,值得参考。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/148200.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

【QGIS入门实战精品教程】6.1:QGIS根据属性条件查询数据(SQL表达式)

文章目录 一、字段过滤二、高级过滤(表达式)一、字段过滤 对于单个字段的查询,可以采用字段过滤,例如,从县区数据中,根据NAME字段,查找出县级市玉门市。操作为:右键县区→打开属性表: 点击左下角,选择name字段。 输入玉门市,回车,选择查找除的属性表记录,此时图斑…

【Linux】入门【更详细,带实操】

Linux全套讲解系列&#xff0c;参考视频-B站韩顺平&#xff0c;本文的讲解更为详细 目录 1、课程内容 2、应用领域 3、概述 4、 Linux和Unix 5、VMware15.5和CentOS7.6安装 6、网络连接三种方式 7、虚拟机克隆 8、虚拟机快照 9、虚拟机迁移删除 10、vmtools 11、目录…

set-ExecutionPolicy RemoteSigned 提示不是内部或外部命令,也不是可运行的程序或批处理文件

这个错误一般发生在使用命令提示符或者PowerShell窗口中找不到set-ExecutionPolicy RemoteSigned。如果你想在命令提示符或者PowerShell窗口运行set-ExecutionPolicy RemoteSigned&#xff0c;你需要搜索打开Window PowerShell ISE&#xff0c;并以管理员身份打开&#xff0c;输…

基于微信小程序的美食外卖管理系统

作者&#xff1a;计算机学姐 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等&#xff0c;“文末源码”。 专栏推荐&#xff1a;前后端分离项目源码、SpringBoot项目源码、Vue项目源码、SSM项目源码 精品专栏&#xff1a;Java精选实战项目…

Tomcat系列漏洞复现

CVE-2017-12615——Tomcat put⽅法任意⽂件写⼊漏洞 漏洞描述 当 Tomcat运⾏在Windows操作系统时&#xff0c;且启⽤了HTTP PUT请求⽅法&#xff08;例如&#xff0c;将 readonly初始化参数由默认值设置为false&#xff09;&#xff0c;攻击者将有可能可通过精⼼构造的攻击请求…

身份安全风险不断上升:企业为何必须立即采取行动

在推动安全AI 模型的过程中&#xff0c;许多组织已转向差异隐私。但这种旨在保护用户数据的工具是否阻碍了创新&#xff1f; 开发人员面临一个艰难的选择&#xff1a;平衡数据隐私或优先考虑精确结果。差分隐私可以保护数据&#xff0c;但通常以牺牲准确性为代价——对于医疗保…

某省公共资源交易中心爬虫逆向分析

目标网站 aHR0cHM6Ly95Z3AuZ2R6d2Z3Lmdvdi5jbi8jLzQ0L3NjenQteHEvP3VzZXJJZD02NzM4OTg2MzkyNjA3NzAzMDQmcm93SWQ9NTI1MDYyMDI2ODg0NzE2NTQ0JnRpbWU9MjAwOC0xMS0yNiZjZXJ0aWZpY2F0ZU5vPTkxNDQwOTA0NjgyNDI2MzU4QyZjZXJ0aWZpY2F0ZVR5cGU9Mjg 一、抓包分析 请求头参数加密 二、…

【学习笔记】手写 Tomcat 五

目录 一、优化 Servlet 创建一个抽象类 继承抽象类 二、三层架构 业务逻辑层 数据访问层 1. 在 Dao 层操作数据库 2. 调用 Dao 层&#xff0c;实现业务逻辑功能 3. 调用 Service 层&#xff0c;响应数据 测试 三、数据库连接池 1. 手写数据库连接池 2. 创建数据库…

2024年9月19日---关于ES6(2)

五 异步编程 5.1 回调函数 5.1.1 概念 回调函数(callback function)&#xff0c;当一个函数作为参数传入另一个参数中&#xff0c;并且它不会立即执行&#xff0c;只有当满足一定条件后该函数才可以执行&#xff0c;这种函数就称为回调函数。 你可以将其理解为 回头再调用的…

GNU编译器(GCC):编译的4个过程及.elf、.list、.map文件功能说明

0 参考资料 GNU-LD-v2.30-中文手册.pdf GNU linker.pdf1 前言 一个完整的编译工具链应该包含以下4个部分&#xff1a; &#xff08;1&#xff09;编译器 &#xff08;2&#xff09;汇编器 &#xff08;3&#xff09;链接器 &#xff08;4&#xff09;lib库 在GNU工具链中&…

开源 AI 智能名片 S2B2C 商城小程序与营销工具的快速迭代

摘要&#xff1a;本文以开源 AI 智能名片 S2B2C 商城小程序为研究对象&#xff0c;探讨在营销工具快速迭代的背景下&#xff0c;该小程序如何借鉴以拼多多为代表的“小程序拼团”、以蘑菇街为代表的“小程序直播”、以花点时间为代表的“小程序按月订花”等经典案例&#xff0c…

数据集-目标检测系列-摩托车检测数据集 motorcycle >> DataBall

数据集-目标检测系列-摩托车检测数据集 motorcycle >> DataBall 数据集-目标检测系列-摩托车&#xff08;motorcycle&#xff09;检测数据集 数据量&#xff1a;1W 想要进一步了解&#xff0c;请联系 DataBall。 DataBall 助力快速掌握数据集的信息和使用方式&#xf…

《论软件架构建模技术与应用》写作框架,软考高级系统架构设计师

论文真题 软件架构风格是描述一类特定应用领域中系统组织方式的惯用模式&#xff0c;反映了领域中诸多系统所共有的结构特征和语义特征&#xff0c;并指导如何将各个模块和子系统有效组织成一个完整的系统。分层架构是一种常见的软件架构风格&#xff0c;能够有效简化设计&…

Python语法进阶之路

一、Python基础 1.1 注释 定义和作用 对代码解释说明&#xff0c;增强可读性 单行注释 # 多行注释 """ 这是一个多行注释 """ 1.2 变量及变量类型 定义和作用 计算机目的是计算&#xff0c;编程是为了更方便计算&#xff0c;计算对象就是…

论前端框架的对比和选择 依据 前端框架的误区

前端框架的对比和选择依据 在前端开发中&#xff0c;有多种框架可供选择&#xff0c;以下是一些常见前端框架的对比和选择依据&#xff1a; 一、Vue.js 特点&#xff1a; 渐进式框架&#xff0c;灵活度高&#xff0c;可以逐步引入到项目中。学习曲线相对较平缓&#xff0c;容…

Attention is All You Need精读

原文开头&#xff0c;不是搬运 dog。All attention is all you need Abstract 摘要 这篇文章的内容源于基于编码器-解码器架构的RNN模型&#xff0c;在其他人的工作中&#xff0c;我们可以发现注意力机制对于提升编码器-解码器架构模型的性能很重要。这篇文章提出了一个比较简…

SpringBoot 更改启动图标

每次springboot开启时&#xff0c;开会显示spring的图标&#xff0c;这个图标是可以修改的。 一、原始的图标样式 二、修改图标样式 https://patorjk.com/software/taag/#pdisplay&fGraffiti&thttps://patorjk.com/software/taag/#pdisplay&fGraffiti&t 在…

MMROTATE 1.X特征图可视化(绘制Heat Map)

本文参考MMYOLO官方的特征图可视化教程&#xff0c;对MMROTATE相关算法进行特征图可视化 1. 新建featmap_vis_demo.py文件 在mmrotate项目文件夹下新建 featmap_vis_demo.py &#xff1a; # Copyright (c) OpenMMLab. All rights reserved. import argparse import os from t…

“吉林一号”宽幅02B系列卫星

离轴四反光学成像系统 1.光学系统参数&#xff1a; 焦距&#xff1a;77.5mm&#xff1b; F/#&#xff1a;7.4&#xff1b; 视场&#xff1a;≥56゜&#xff1b; 光谱范围&#xff1a;400nm&#xff5e;1000nm。 2.说明&#xff1a; 光学系统采用离轴全反射式结构&#xff0c;整…

CIM平台应用的一些思考

今天中午看了一些书&#xff0c;讲致幻剂在疾病治疗的一些作用。致幻剂包括毒蘑菇等这类东西&#xff0c;有精神疾病或其他心里疾病的患者在吸食或注射&#xff08;专业医生的指导下&#xff09;会忘记或减轻身体的痛苦&#xff0c;忘记死亡&#xff0c;相信永生&#xff0c;治…