You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为Scraper类实现支持指定页数或爬取全部页面的方法?

问题描述

我有一个用于网站爬取的Scraper类,它使用requests库的会话功能,代码大致如下:

class Scraper:
    def scrape_page(self):
        """Scrapes the current page"""

        # do something
        self.request_next_page()

    def request_next_page(self):
        """ Finds the 'next' link if available and requests next page"""

我希望在该类中新增一个方法,支持传入参数以实现两种爬取模式:爬取指定n个页面,或爬取所有页面直到没有下一页为止。现有方法运行正常,但我不清楚如何让参数既可以是整数,又可以用类似True这样的标识来表示爬取全部页面。我想要实现类似如下的方法:

def scrape_pages(self, num):
        """Scrape n number of pages"""

调用方式如下:

>>> s = Scraper()
>>> s.scrape_pages(5)       # 爬取前5个页面

或者:

>>> s = Scraper()
>>> s.scrape_pages(all)     # 这里的all可以是True或其他可行的标识,我不确定用什么合适

我知道可以用两个独立函数,或者通过if语句判断参数是整数还是True,再分别使用for循环或while循环,但想了解是否有更优的实现方式?我注意到.split()方法有类似的逻辑,maxsplit参数可设置限制或不设置,但我不熟悉C语言,无法理解其实现原理。


最优实现方案

这里推荐用默认参数+统一循环逻辑的写法,既符合Python的惯用风格,又能避免代码冗余,和你提到的split()逻辑思路一致。

实现思路

  1. 用None作为参数默认值,语义上代表"爬取全部页面",整数则代表指定爬取页数
  2. 用一个while循环统一处理两种场景,通过条件判断控制停止时机,避免重复写for和while的逻辑

完整代码实现

class Scraper:
    def scrape_page(self):
        """Scrapes the current page"""
        # 这里写实际爬取页面的业务逻辑
        print("正在爬取当前页面")
        # 假设爬取成功返回True,失败则返回False
        return True

    def request_next_page(self):
        """查找并请求下一页,返回True表示有下一页,False表示无下页"""
        # 这里写实际获取下一页链接并请求的逻辑
        print("正在请求下一页")
        # 示例返回,实际根据网站是否存在下一页修改
        return True

    def scrape_pages(self, num_pages=None):
        """
        爬取指定数量页面或全部页面
        :param num_pages: 整数=指定爬取页数;None=爬取全部页面
        """
        page_count = 0
        while True:
            # 先爬取当前页,失败则直接终止
            if not self.scrape_page():
                break
            
            page_count += 1
            # 如果是指定页数模式,达到数量就停止
            if isinstance(num_pages, int) and page_count >= num_pages:
                break
            
            # 请求下一页,没有下页则终止
            if not self.request_next_page():
                break

调用示例

s = Scraper()
s.scrape_pages(5)  # 爬取前5页
s.scrape_pages()   # 爬取全部页面(不传参数,使用默认值None)
# 也可以显式传入None
s.scrape_pages(None)

方案优势

  • 单一入口:只用一个方法覆盖两种场景,无需拆分多个函数,符合DRY原则
  • 可读性强:None的语义清晰,和str.split(maxsplit=None)的设计逻辑一致,Python开发者一眼就能理解
  • 代码复用:循环逻辑只写一次,避免了for和while的重复代码
  • 扩展性好:后续要加其他停止条件(比如爬取到特定内容停止),只需在循环内新增判断即可

如果你坚持想用True表示爬取全部,也可以调整参数默认值,逻辑类似:

def scrape_pages(self, num_pages=True):
    page_count = 0
    while True:
        if not self.scrape_page():
            break
        
        page_count += 1
        if isinstance(num_pages, int) and page_count >= num_pages:
            break
        
        # 如果传入False可以直接终止,不过这个场景用得少
        if not num_pages:
            break
        
        if not self.request_next_page():
            break

调用时:

s.scrape_pages(5)    # 指定5页
s.scrape_pages(True) # 爬取全部

不过还是更推荐用None的写法,因为它更贴合Python的API设计惯例。

内容的提问来源于stack exchange,提问作者dev_null

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 13:15:16