猫头虎AI开源分享:如何批量获取稀土掘金社区文章阅读量暨文章阅读量数据批量提取解决方案
在数据分析和内容创作的过程中,获取文章的阅读量数据对于衡量文章的受欢迎程度、分析内容趋势具有重要意义。特别是对于像稀土掘金这样的大型技术社区平台,手动提取每篇文章的阅读量显得既繁琐又低效。因此,我们可以通过编写一个简单的 Python 工具,批量提取这些数据,自动化完成这一任务。
本文将为大家介绍如何用 Python 编写一个工具,来从稀土掘金社区批量提取文章的阅读量数据。本文的重点是使用requests获取网页数据,使用BeautifulSoup解析 HTML 内容,并利用openpyxl操作 Excel 文件,最后通过代理池和异常重试机制保证程序的稳定性和高效性。
文章目录
- 猫头虎AI开源分享:如何批量获取稀土掘金社区文章阅读量暨文章阅读量数据批量提取解决方案
- 环境准备
- 安装必要的依赖库
- 基础版代码
- 结果问题及解决方案
- 引入动态网络 IP 代理
- 出现新问题:部分数据无法获取
- 加入异常重试机制
- 总结
环境准备
在开始之前,你需要准备好以下环境和工具:
- Python 环境:确保你的计算机上已安装 Python。
- Excel 表格:用于存储稀土掘金文章的链接,并写入对应的阅读量数据。
安装必要的依赖库
在开始编写代码之前,我们需要安装一些 Python 库:
pipinstallrequests beautifulsoup4 openpyxlrequests:用于发送 HTTP 请求获取网页数据。beautifulsoup4:用于解析 HTML 页面。openpyxl:用于操作 Excel 文件,将结果写入表格。
基础版代码
我们从一个简单的基础版开始,这个版本能够读取一个 Excel 文件,提取其中的 URL,获取每篇文章的阅读量并写回到表格中。
# -*- coding: utf-8 -*-importtimeimportrequestsfrombs4importBeautifulSoupfromopenpyxlimportload_workbook# ===== 配置区域 =====# Excel 文件名(就在当前目录下)INPUT_FILE="juejin-1.xlsx"# 输出文件名OUTPUT_FILE="juejin-1_带阅读量.xlsx"# 从第几行开始读取(如果第1行是表头,就从2开始)START_ROW=2# 第一列是链接,第二列写入阅读量URL_COL=1VIEWS_COL=2# 每次请求间隔(秒),防止请求过快SLEEP_SECONDS=1# ===== 核心程序 =====defget_views_from_url(url:str)->str:""" 给定网址,返回页面中 <span class="views-count"> 内的阅读量数字字符串。 如果未找到,则返回空字符串。 """headers={"User-Agent":("Mozilla/5.0 (Windows NT 10.0; Win64; x64) ""AppleWebKit/537.36 (KHTML, like Gecko) ""Chrome/129.0 Safari/537.36")}resp=requests.get(url,headers=headers,timeout=10)resp.raise_for_status()soup=BeautifulSoup(resp.text,"html.parser")# 根据你给的代码片段:# <span class="views-count">=soup.select_one("span.views-count")ifnotspan:return""text=span.get_text(strip=True)returntextdefmain():wb=load_workbook(INPUT_FILE)# 默认使用当前活动工作表,如需指定,可以改成 wb["Sheet1"]ws=wb.active max_row=ws.max_rowprint(f"共检测到{max_row}行数据,开始处理……")forrowinrange(START_ROW,max_row+1):url=ws.cell(row=row,column=URL_COL).valueifnoturl:continue# 跳过空行print(f"第{row}行,正在处理:{url}")try:views=get_views_from_url(url)ifviews=="":print(f" 未找到阅读量,写入空值。")else:print(f" 获取到阅读量:{views}")exceptExceptionase:print(f" 发生错误:{e}")views=""# 出错就写空,避免中断整个程序ws.cell(row=row,column=VIEWS_COL,value=views)# 稍作停顿,避免对服务器压力过大time.sleep(SLEEP_SECONDS)wb.save(OUTPUT_FILE)print(f"处理完成,结果已保存到:{OUTPUT_FILE}")if__name__=="__main__":main()结果问题及解决方案
运行上述代码后,你可能会发现当请求数量增加时,程序会遇到一些问题,例如部分页面无法获取阅读量或返回 0 阅读量。这是因为网站会对频繁的请求做出限制,防止被当作爬虫攻击。为了解决这个问题,我们需要使用动态网络 IP(代理)来避免请求被封禁。
引入动态网络 IP 代理
为了防止频繁请求导致 IP 被封禁,我们可以使用一个代理池。这里推荐使用 1000个稳定IP,来提供稳定的代理。
# 代理设置PROXY={"http":"http://ip.cc","https":"http://ip.cc"# 自定义更换}resp=requests.get(url,headers=headers,proxies=PROXY,timeout=10)resp.raise_for_status()出现新问题:部分数据无法获取
即使使用了代理,可能还是会遇到部分请求失败或者读取到的数据为空的情况。这时我们可以在程序中加入异常重试机制,确保请求失败时可以自动重试,增加数据抓取的成功率。
加入异常重试机制
通过引入异常重试机制,我们可以使得程序在面对请求失败、页面没有数据或者返回为 0 的情况时自动重试,直到获取有效的阅读量数据为止。
# -*- coding: utf-8 -*-importrandomimporttimeimportrequestsfrombs4importBeautifulSoupfromopenpyxlimportload_workbook# ===== 配置区域 =====# Excel 文件名(就在当前目录下)INPUT_FILE="juejin-1.xlsx"# 输出文件名OUTPUT_FILE="juejin-1_带阅读量.xlsx"# 从第几行开始读取(如果第1行是表头,就从2开始)START_ROW=2# 第一列是链接,第二列写入阅读量URL_COL=1VIEWS_COL=2# 每次请求间隔(秒),防止请求过快BASE_SLEEP=1.2# 额外随机等待(秒)RANDOM_SLEEP=(0.5,1.5)# 代理设置PROXY={"http":"http://ip.cc","https":"http://ip.cc"}# ===== 核心程序 =====HEADERS={"User-Agent":("Mozilla/5.0 (Windows NT 10.0; Win64; x64) ""AppleWebKit/537.36 (KHTML, like Gecko) ""Chrome/129.0 Safari/537.36")}# ===================# 核心抓取函数,带重试# ===================defextract_digits(text:str)->str:"""提取纯数字,例如 '阅读 54 次' → '54'"""return"".join(chforchintextifch.isdigit())# ===================# 核心抓取函数(失败/为0都会重试)# ===================deffetch_view_count(url:str,retry:int=1)->str:""" - 请求失败 → 重试 - 标签不存在 → 重试 - 找到但数字为空 → 重试 - 数字为 '0' → 也当成失败重试 - 全失败 → 返回空 """attempt=0whileattempt<=retry:ifattempt>0:print(f" ↻ 重试第{attempt}次...")time.sleep(BASE_SLEEP+random.uniform(*RANDOM_SLEEP))try:resp=requests.get(url,headers=HEADERS,proxies=PROXY,timeout=15)resp.raise_for_status()soup=BeautifulSoup(resp.text,"html.parser")span=soup.select_one("span.views-count")ifnotspan:print(" 未找到 span.views-count 元素")else:raw=span.get_text(strip=True)digits=extract_digits(raw)ifnotdigits:print(f" 找到元素但无数字:{raw!r}")elifdigits=="0":print(" 获取到 0,视为失败,将继续重试…")else:returndigitsexceptExceptionase:print(f" 请求失败:{e}")attempt+=1return""# ===================# 主程序(逐条写入 Excel)# ===================defmain():wb=load_workbook(INPUT_FILE)ws=wb.active max_row=ws.max_rowprint(f"共{max_row}行数据,从第{START_ROW}行开始处理。\n")forrowinrange(START_ROW,max_row+1):url=ws.cell(row=row,column=URL_COL).valueifnoturl:continueprint(f"第{row}行,正在处理:{url}")# 获取阅读量views=fetch_view_count(url,retry=1)ifviews:print(f" ✓ 获取到阅读量:{views}")else:print(" × 未能获取到有效阅读量(写入空)")# ⭐ 立即写入本行数据ws.cell(row=row,column=VIEWS_COL,value=views)# ⭐ 每条数据获取后立即保存文件wb.save(OUTPUT_FILE)print(" → 已立即写入 Excel 并保存。\n")print(f"全部完成,结果已保存到:{OUTPUT_FILE}")if__name__=="__main__":main()总结
通过引入代理池和异常重试机制,我们能够确保即使在高频率请求下,程序依然能稳定运行,准确地获取到稀土掘金文章的阅读量数据。如果你遇到任何问题,或者想进一步改进该工具,欢迎随时与我交流!
此外,使用 1000个稳定IP 可以帮助你轻松解决代理问题,提高爬虫程序的稳定性。