告别手动保存!用Python自动化下载雪球文章并生成带书签的PDF合集

张开发
2026/4/19 13:31:59 15 分钟阅读

分享文章

告别手动保存!用Python自动化下载雪球文章并生成带书签的PDF合集
告别手动保存用Python自动化下载雪球文章并生成带书签的PDF合集每次在雪球上看到有价值的投资分析文章你是不是也习惯性地点击收藏但收藏夹里的内容越来越多查找起来反而更麻烦。更糟的是有些文章可能因为各种原因被删除或修改手动保存的本地副本又杂乱无章。作为一名经常研究市场动态的技术爱好者我花了三个月时间开发了一套自动化解决方案现在分享给同样有这种痛点的你。这套工具的核心价值在于一键抓取指定作者的全部历史文章自动生成结构清晰、带书签导航的PDF合集。不仅保留了原文的完整格式还能按照发布时间、点赞数等维度进行智能排序。下面我就从环境准备到完整实现详细拆解每个技术环节。1. 环境准备与基础工具链工欲善其事必先利其器。我们需要搭建一个既能高效抓取网页内容又能完美保留排版样式的处理流水线。以下是经过我实际验证的工具组合# 核心依赖清单 requirements [ requests2.28.1, # 网络请求 beautifulsoup44.11.1, # HTML解析 pdfkit1.0.0, # HTML转PDF pandas1.5.0, # 数据整理 PyPDF22.11.0, # PDF合并 ]安装这些库只需一行命令pip install requests beautifulsoup4 pdfkit pandas PyPDF2注意pdfkit需要额外安装wkhtmltopdf引擎Windows用户可从官网下载安装包Mac用户建议使用brew install wkhtmltopdf我对比过三种HTML转PDF方案下面是性能测试数据方案渲染质量速度中文支持书签生成pdfkit★★★★☆中速完美需手动weasyprint★★★☆☆快速一般不支持playwright★★★★★慢速完美自动最终选择pdfkit是因为它在质量与效率之间取得了最佳平衡虽然书签生成需要额外处理但稳定性远超其他方案。2. 雪球文章抓取实战雪球的网页结构经过多次改版但核心数据接口仍然保持稳定。通过分析XHR请求我发现了一个隐藏的API接口def fetch_xueqiu_articles(user_id, max_page10): 抓取指定用户的所有文章 articles [] base_url fhttps://xueqiu.com/u/{user_id} for page in range(1, max_page 1): params { page: page, size: 20 # 每页数量 } headers { User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64), X-Requested-With: XMLHttpRequest } try: response requests.get(base_url, paramsparams, headersheaders) data response.json() articles.extend(data[list]) except Exception as e: print(f第{page}页抓取失败: {str(e)}) return articles这个函数会返回包含以下字段的JSON数据title: 文章标题description: 摘要内容created_at: 发布时间戳view_count: 阅读数reward_count: 打赏数提示雪球对频繁请求有防护机制建议在请求间添加time.sleep(random.uniform(1, 3))模拟人工操作获取到文章列表后我们需要用BeautifulSoup清洗HTML内容def clean_html(content): 净化雪球文章HTML soup BeautifulSoup(content, html.parser) # 移除广告元素 for ad in soup.select(.ad-container, .recommend-article): ad.decompose() # 修复图片链接 for img in soup.select(img): if img.get(data-original): img[src] img[data-original] return str(soup)3. 生成带书签的PDF这是整个流程最关键的环节。普通的HTML转PDF会丢失文档结构我们需要通过以下步骤实现智能书签def html_to_pdf_with_bookmark(html_path, pdf_path, title): 转换HTML为带书签的PDF options { encoding: UTF-8, page-size: A4, margin-top: 15mm, margin-right: 15mm, margin-bottom: 15mm, margin-left: 15mm, quiet: , title: title, } pdfkit.from_file(html_path, pdf_path, optionsoptions) # 添加PDF书签 with open(pdf_path, rb) as f: reader PdfReader(f) writer PdfWriter() for page in reader.pages: writer.add_page(page) # 添加根书签 writer.add_outline_item(title, 0) with open(pdf_path, wb) as f_out: writer.write(f_out)实际应用中我会先批量生成单篇文章PDF再用下面的方法合并def merge_pdfs(pdf_list, output_path, bookmarks): 合并PDF并保留书签结构 merger PdfMerger() for idx, pdf in enumerate(pdf_list): merger.append(pdf) if idx len(bookmarks): merger.add_outline_item(bookmarks[idx], idx) merger.write(output_path) merger.close()4. 高级功能扩展基础功能实现后我进一步优化了三个实用特性1. 智能排序系统def sort_articles(articles, methodtime): 支持多种排序方式 if method time: return sorted(articles, keylambda x: x[created_at]) elif method popular: return sorted(articles, keylambda x: -x[view_count]) elif method comments: return sorted(articles, keylambda x: -x[comment_count])2. 元数据导出def export_metadata(articles, output_formatcsv): 导出文章统计数据 df pd.DataFrame(articles) if output_format csv: df.to_csv(articles_meta.csv, indexFalse) elif output_format excel: df.to_excel(articles_meta.xlsx, indexFalse)3. 增量更新机制def check_updates(user_id, last_crawl_time): 只抓取新发布的文章 new_articles [] current_page 1 while True: batch fetch_articles(user_id, pagecurrent_page) if not batch: break new_in_batch [a for a in batch if a[created_at] last_crawl_time] new_articles.extend(new_in_batch) if len(new_in_batch) len(batch): break current_page 1 return new_articles5. 异常处理与性能优化在实际运行中我遇到了几个典型问题及解决方案常见故障排查表现象可能原因解决方案中文乱码编码声明缺失在HTML添加meta charset图片加载失败防盗链机制修改请求头Referer字段PDF生成超时复杂CSS渲染设置超时参数timeout60书签跳转偏移页码计算错误使用PyPDF2的add_outline_item对于大规模抓取建议采用以下优化策略使用异步请求库aiohttp提升IO效率实现断点续传功能分布式任务队列CeleryRabbitMQ# 异步抓取示例 async def async_fetch(url): async with aiohttp.ClientSession() as session: async with session.get(url) as response: return await response.text()经过三个月的迭代这套系统已经稳定处理了超过5万篇雪球文章。最让我自豪的是为一个私募基金客户自动整理的行业研究报告库包含327位分析师的1.2万篇文章按行业、时间、热度等多维度分类PDF总大小控制在800MB以内书签层级深度达到4级。

更多文章