如何用BeautifulSoup获取无明确页码网站的总页数并优化分页?
分页爬取问题:无总页数时的处理方案与代码优化
一、如何确定仅显示上/下一页按钮网站的总页数
针对这类无明确总页数的网站,可通过以下方法判断:
- 遍历至无有效数据:持续请求下一页,直到页面返回空结果、404错误,或返回内容与上一页完全重复(部分网站会在超出总页数后仍返回最后一页内容)。
- 检查下一页按钮状态:每次请求后,查找页面中的「下一页」按钮(比如通过类名
next-page、page-link next,或rel="next"属性),若按钮不存在或禁用,说明当前是最后一页。 - 挖掘页面隐藏数据:查看页面源码,寻找是否有隐藏标签、Meta标签或JS变量存储总页数(比如
totalPages、pagination.total这类字段)。 - 通过结果总数反推:如果页面显示搜索结果总条数(如「共108条学校信息」),结合每页显示条数(如每页10条),用
总条数 ÷ 每页条数向上取整得到总页数。
二、分页代码优化方案
原有代码依赖手动指定页数范围,灵活性差,优化后可实现自动遍历直到最后一页:
from myWork.commons import url_parser, write import time # 可选,用于添加请求延时,降低反爬风险 def data_fetch(url): school_info = [] page_number = 0 last_page_content = None # 检测是否重复返回最后一页内容 while True: next_web_page = f"{url}?page={page_number}" soup = url_parser(next_web_page) # 捕获异常,避免因页面结构变化导致程序崩溃 try: search_results = soup.find('section', {'id': 'search-results'}).find(class_='container').find(class_='row') except AttributeError: # 找不到结果区域,说明无数据,退出循环 break # 检查当前页是否有有效学校数据(需根据页面实际元素调整选择器) school_cards = search_results.find_all(class_='school-card') if not school_cards: break # 检测内容是否重复,避免无限循环 current_content = search_results.get_text(strip=True) if current_content == last_page_content: break last_page_content = current_content # 处理当前页数据(替换为你的原有逻辑) # for card in school_cards: # 提取学校信息并添加到school_info列表 # 检查是否存在下一页按钮(需根据网站实际按钮调整选择器) next_button = soup.find('a', class_='page-link', text='Next') # 也可通过rel属性查找:next_button = soup.find('a', {'rel': 'next'}) if not next_button: break page_number += 1 time.sleep(1) # 可选,添加1秒延时 def main(): url = "https://skoodos.com/schools-in-uttarakhand" data_fetch(url) if __name__ == "__main__": main()
优化关键点说明
- 自动终止循环:通过「无有效数据」「无下一页按钮」「内容重复」三个条件自动终止,无需手动指定页数范围。
- 异常防护:捕获
AttributeError,避免页面结构变化导致程序崩溃。 - 防重复爬取:检测内容重复,避免部分网站重复返回最后一页内容引发无限循环。
- 反爬友好:可选添加请求延时,降低被网站封禁的风险。
内容的提问来源于stack exchange,提问作者theycallmepix
相关产品推荐
相关产品推荐

