支持私有化部署
AI知识库

53AI知识库

学习大模型的前沿技术与行业应用场景


爬虫新宠Crawlee:解锁数据抓取与自动化的超能力

发布日期:2025-04-22 08:23:10 浏览次数: 1551 作者:测试工程师成长之路
推荐语

探索新一代爬虫工具Crawlee,开启数据抓取与自动化的新纪元。

核心内容:
1. Crawlee作为下一代爬虫工具的突出特性
2. Crawlee与现有爬虫框架的对比优势
3. Crawlee在数据挖掘、自动化测试和网页监控中的应用场景

杨芳贤
53A创始人/腾讯云(TVP)最具价值专家

 点击上方【测试工程师成长之路】关注我们

亲爱的小伙伴们,由于微信公众号改版,打乱了发布时间,为了保证大家可以及时收到文章的推送,可以点击上方蓝字关注测试工程师成长之路,并设为星标就可以第一时间收到推送哦!








感谢您抽出

.

.

阅读本文

 

一、Crawlee:爬虫界的明日之星

在数据驱动的时代,网络爬虫和浏览器自动化工具成为了获取信息的得力助手。从学术研究的数据收集,到商业领域的市场情报分析,再到搜索引擎的数据索引,这些工具都发挥着不可或缺的作用。Crawlee作为一款下一代网络爬虫与浏览器自动化工具,正逐渐崭露头角,以其强大的功能和卓越的性能,为开发者们带来了全新的体验。它不仅能够轻松应对复杂的网络环境和反爬虫机制,还提供了简洁高效的编程接口,使得数据抓取和浏览器自动化任务变得更加简单和高效。接下来,让我们一起深入探索Crawlee的奇妙世界。

二、Crawlee 初相识

Crawlee 是什么

CrawleeApify团队精心打造的一款开源网络爬虫与浏览器自动化库,它犹如一把万能钥匙,为开发者打开了通往高效数据抓取和浏览器自动化操作的大门。其设计初衷是为了简化和加速网络爬虫及浏览器自动化任务的开发过程,让开发者能够更加专注于业务逻辑的实现,而无需过多地纠结于底层的技术细节。凭借着简洁易用的APICrawlee能够帮助开发者迅速实现网页内容的抓取以及浏览器自动化操作,无论是数据挖掘、自动化测试还是网页监控等领域,它都能大显身手。

Crawlee支持多种编程语言,其中包括广泛使用的JavaScriptPythonTypeScript 。这使得不同技术背景的开发者都能轻松上手,根据自己的喜好和项目需求选择合适的语言进行开发。在当今数字化时代,数据的价值不言而喻,Crawlee在数据挖掘领域发挥着重要作用,能够帮助企业从海量的网络数据中提取有价值的信息,为决策提供有力支持;在自动化测试方面,Crawlee可以模拟用户在浏览器中的各种操作,实现对网页应用的自动化测试,提高测试效率和准确性;而在网页监控领域,它能够实时监测网页的变化,及时发现并通知用户,确保网站的正常运行。

为什么选择 Crawlee

在爬虫领域,已经存在着许多优秀的框架,如ScrapyBeautifulSoupSelenium等,那为什么Crawlee能脱颖而出,吸引众多开发者的目光呢?让我们通过对比来一探究竟。

Scrapy是一款强大的Python爬虫框架,它在处理大规模数据抓取任务时表现出色,具有高效的异步处理能力和丰富的中间件扩展。然而,当面对需要与JavaScript动态交互的网页时,Scrapy就显得有些力不从心了。因为它主要侧重于传统的HTTP请求和静态网页的抓取,对于那些依赖JavaScript渲染的动态内容,很难直接获取到完整的数据。

BeautifulSoup则是一个简单易用的HTML/XML解析库,通常与Requests库配合使用。它的优势在于简单上手,能够方便地从HTMLXML文档中提取数据 。但它的功能相对较为单一,主要专注于解析网页结构,对于复杂的爬虫任务,如处理动态内容、自动扩展、代理轮换等,它无法提供全面的支持。

Selenium作为一个浏览器自动化工具,支持多种编程语言,能够模拟用户在浏览器中的操作,处理动态加载内容和复杂用户交互。不过,Selenium在性能方面存在一定的局限性,它的运行速度相对较慢,而且在处理大规模任务时,资源消耗较大。此外,Selenium缺少持久化队列和自动扩展功能,这在一定程度上限制了它在一些场景下的应用。

相比之下,Crawlee的优势就显而易见了。首先,Crawlee在处理动态内容方面具有得天独厚的优势。它基于PlaywrightPuppeteer构建,可以模拟真实用户在浏览器中的操作,如点击、滚动、输入等,能够轻松应对复杂的网页交互场景,如验证码识别、滑动验证等。这使得它在抓取那些依赖JavaScript动态加载的网页时,能够获取到完整且准确的数据。

其次,Crawlee具备自动扩展功能。它可以根据可用的系统资源自动管理并发,从而提高爬虫的效率。在处理大规模抓取任务时,能够根据任务的需求动态调整资源分配,确保任务能够高效、稳定地运行。这种自动扩展的能力,使得Crawlee在面对大量数据抓取任务时,能够充分发挥其性能优势,大大节省了开发时间和资源成本。

再者,Crawlee内置了强大的代理轮换功能。在网络爬虫过程中,使用代理服务器是绕过地理限制、避免IP被封的重要手段之一。Crawlee的代理轮换功能能够智能地管理代理,丢弃经常超时、返回网络错误或不良HTTP代码(如401403)的代理,以保持代理的健康状态,从而提高爬取的稳定性和可靠性。这一功能使得Crawlee在面对各种反爬虫机制时,能够更加灵活地应对,确保爬虫任务的顺利进行。

此外,Crawlee还提供了灵活的队列管理功能,支持多种队列类型,如优先级队列、定时队列等。开发者可以根据需求调整抓取策略,合理安排任务的执行顺序。同时,Crawlee支持将抓取到的数据存储到多种数据库和存储系统中,如MySQLMongoDBElasticsearch等,方便后续的数据处理和分析。丰富的插件生态也是Crawlee的一大亮点,活跃的社区为开发者提供了大量实用插件,如代理插件、数据分析插件等,进一步增强了Crawlee的功能,助力开发者高效完成爬虫项目。

三、Crawlee 实战:从安装到数据爬取

安装 Crawlee

在开始使用Crawlee之前,我们需要先将其安装到我们的开发环境中。Crawlee支持使用pip进行安装,pipPython的包管理工具,它可以帮助我们方便地安装、升级和管理Python包。在安装Crawlee时,我们还需要一并安装Playwright,因为Crawlee是基于Playwright构建的,Playwright提供了对浏览器自动化操作的支持。在命令行中执行以下命令:

# Crawlee 是crawleePyPI 上的软件包。此软件包包含核心功能,而其他功能则作为可选附加功能提供,以尽量减少依赖性和软件包大小。
# 你可以安装具有所有功能的 Crawlee,也可以仅选择所需的功能。要使用pip包管理器安装它
python -m pip install 'crawlee[all]'
# 验证是否安装成功
python -c 'import crawlee; print(crawlee.__version__)'
# 安装 Playwright
playwright install

在安装过程中,pip会自动下载Crawlee及其依赖项,并将它们安装到Python的环境中。请确保你的Python环境已经正确配置,并且网络连接正常,以避免安装过程中出现问题。如果在安装过程中遇到权限问题,可以尝试使用管理员权限运行命令行,或者使用虚拟环境来隔离项目依赖,避免对系统环境造成影响。安装完成后,我们就可以在Python项目中引入Crawlee,开始我们的数据爬取之旅了。

基本爬虫结构

在使用Crawlee进行数据爬取时,我们需要先了解其基本的爬虫结构。下面我们以爬取某网站文章列表为例,来讲解如何使用Crawlee构建一个简单的爬虫。

首先,我们需要导入Crawlee库以及相关的模块。在Python中,我们可以使用以下代码导入:

from crawlee import Request, Spider, run_spider

在这里,Request用于定义HTTP请求,Spider是爬虫的基类,我们需要继承它来创建自己的爬虫,run_spider则用于启动爬虫。

接下来,我们创建一个爬虫类,继承自Spider。在这个类中,我们需要定义一个start_requests方法,这个方法用于生成初始的请求。例如:

class ArticleSpider(Spider):
    async def start_requests(self):
        yield Request(url='https://testerroad.com/articles', callback=self.parse_articles)

在这个例子中,我们生成了一个请求,并指定了一个回调函数parse_articles,用于处理请求返回的响应。

然后,我们定义parse_articles方法,这个方法用于解析响应,提取我们需要的数据。例如:

async def parse_articles(self, response):
    articles = response.css('div.article')
    for article in articles:
        title = article.css('h2.title::text').get()
        link = article.css('a::attr(href)').get()
        yield {
            'title': title,
            'link': link
        }

在这个方法中,我们使用response.css来选择页面中的元素,div.article表示选择所有classarticlediv元素。然后,我们通过css选择器分别提取文章的标题和链接,并将它们作为一个字典返回。这里使用yield关键字,是因为我们可能会提取到多个文章的数据,yield可以将这些数据逐个返回,而不是一次性返回所有数据,这样可以节省内存。

数据爬取实战

下面我们通过一个完整的代码示例,来展示如何使用Crawlee爬取网页内容并将爬取的数据保存,以下是一个使用crawleePlaywrightPython示例,演示如何爬取动态网页(以电商网站商品列表为例)并存储数据。

from crawlee import (
PlaywrightCrawler,
Request,
RequestQueue,
Dataset,
ProxyConfiguration
)
from playwright.async_api import Page
import asyncio

'''
 @Author  : TesterRoad
 @Time    : 2025/3
 @Desc    : 公众号:测试工程师成长之路
 @Software: PyCharm
'''


# 目标网站示例(请替换为实际可爬取的网站)
TARGET_URL = 'https://www.testerroad.com.cn/products'

async def handle_page(page: Page, request: Request):
    try:
        # 等待商品列表加载完成
        await page.wait_for_selector('.product-item', timeout=5000)

        # 获取所有商品项
        product_items = await page.query_selector_all('.product-item')

        results = []
        for item in product_items:
            # 提取商品数据
            title = await item.text_content('.product-title')
            price = await item.text_content('.price')
            description = await item.text_content('.description')

            results.append({
                'title': title.strip() if title elseNone,
                'price': float(price.replace('$''')) if price elseNone,
                'description': description.strip() if description elseNone,
                'url': page.url
            })

        # 将数据保存到数据集
        await Dataset.push_data(results)

        # 处理分页(示例:查找下一页按钮)
        next_button = await page.query_selector('.pagination .next')
        if next_button:
            next_url = await next_button.get_attribute('href')
            if next_url:
                await RequestQueue.add_request(
                    Request(url=page.url.split('?')[0] + next_url)
                )

    except Exception as e:
        print(f'Error processing {request.url}{str(e)}')

# 配置爬虫
async def main():
    # 初始化请求队列
    request_queue = await RequestQueue.open()
    await request_queue.add_request(Request(url=TARGET_URL))

    # 代理配置(可选)
    proxy_config = ProxyConfiguration({
        'proxyGroups': ['RESIDENTIAL']
    })

    # 创建爬虫实例
    crawler = PlaywrightCrawler(
        request_queue=request_queue,
        handle_page_function=handle_page,
        proxy_configuration=proxy_config,
        browser_launch_options={
            'headless'True,  # 无头模式
            'timeout'15000
        },
        navigation_options={
            'wait_until''domcontentloaded',
            'timeout'30000
        }
    )

    # 运行爬虫
    await crawler.run()

    # 导出数据到JSON文件
    await Dataset.export_to_json('products.json')

if __name__ == '__main__':
    asyncio.run(main())

代码解析

  1. 1. 依赖导入
  • • PlaywrightCrawler: 基于Playwright的爬虫类
  • • Request/RequestQueue: 管理请求队列
  • • Dataset: 数据存储模块
  • • ProxyConfiguration: 代理配置
  • 2. 页面处理函数 (handle_page)
    • • 等待商品列表加载
    • • 使用CSS选择器提取数据
    • • 自动处理分页逻辑
    • • 错误处理机制
  • 3. 核心配置
    • • 代理设置(需有效代理账号)
    • • 浏览器启动参数
    • • 导航超时设置
  • 4. 数据存储
    • • 使用内置Dataset模块
    • • 最终导出为JSON文件

    四、Crawlee 高级应用与技巧

    处理复杂网页结构

    在实际的网络爬虫任务中,我们经常会遇到各种复杂的网页结构,如嵌套页面、分页等,这些情况增加了数据爬取的难度。不过,Crawlee提供了强大的功能和灵活的方法,能够帮助我们轻松应对这些挑战。

    对于嵌套页面的爬取,Crawlee允许我们在回调函数中生成新的请求。例如,在爬取电商网站时,我们可能需要从商品列表页面进入商品详情页面,获取更详细的商品信息。我们可以在解析商品列表页面的回调函数中,为每个商品链接生成一个新的请求,并指定一个新的回调函数来处理商品详情页面。代码示例如下:

    async def parse_product_list(self, response):
        products = response.css('div.product-item')
        for product in products:
            product_link = product.css('a::attr(href)').get()
            yield Request(url=product_link, callback=self.parse_product_detail)

    async def parse_product_detail(self, response):
        title = response.css('h1.product-title::text').get()
        price = response.css('span.product-price::text').get()
        description = response.css('div.product-description::text').get()
        yield {
            'title': title,
            'price': price,
            'description': description
        }

    在上述代码中,parse_product_list方法负责解析商品列表页面,提取每个商品的链接,并为每个链接生成一个新的请求,交给parse_product_detail方法处理。parse_product_detail方法则负责解析商品详情页面,提取商品的标题、价格和描述等信息。

    当面对分页的网页时,Crawlee同样能够轻松处理。我们可以通过分析网页的分页规律,在回调函数中生成不同页码的请求。例如,对于一个分页的新闻列表页面,每页有 10 条新闻,我们可以通过循环生成不同页码的请求,实现对所有新闻的爬取。代码示例如下:

    async def start_requests(self):
        base_url = 'https://testerroad.com/news?page={}'
        for page in range(111):  # 假设共有10页
            url = base_url.format(page)
            yield Request(url=url, callback=self.parse_news_list)

    async def parse_news_list(self, response):
        news = response.css('div.news-item')
        for item in news:
            title = item.css('h2.news-title::text').get()
            link = item.css('a::attr(href)').get()
            yield {
                'title': title,
                'link': link
            }

    在这个示例中,start_requests方法通过循环生成 1 到 10 页的请求,每个请求的URL根据页码进行格式化。parse_news_list方法负责解析每页的新闻列表,提取新闻的标题和链接。

    应对反爬虫机制

    在网络爬虫的世界里,反爬虫机制是我们经常面临的挑战。幸运的是,Crawlee内置了一系列强大的防屏蔽功能,能够帮助我们有效地应对反爬虫,确保爬虫任务的顺利进行。

    Crawlee提供了代理轮换功能,通过使用代理服务器,我们可以隐藏真实的IP地址,降低被目标网站封禁的风险。Crawlee能够智能地管理代理,自动丢弃那些经常超时、返回网络错误或不良HTTP代码(如401403)的代理,以保持代理的健康状态。在配置代理时,我们可以通过设置代理列表来实现代理轮换。代码示例如下:

    from crawlee import Request, Spider, run_spider

    '''
     @Author  : TesterRoad
     @Time    : 2025/3
     @Desc    : 公众号:测试工程师成长之路
     @Software: PyCharm
    '''


    class MySpider(Spider):
        async def start_requests(self):
            proxy_list = [
                'http://proxy1.testerroad.com:8080',
                'http://proxy2.testerroad.com:8080',
                'http://proxy3.testerroad.com:8080'
            ]
            for proxy in proxy_list:
                yield Request(url='https://testerroad.com', proxy=proxy, callback=self.parse_page)
        async def parse_page(self, response):
            # 处理响应数据
            pass
            
    if __name__ == "__main__":
        run_spider(MySpider)

    在上述代码中,我们定义了一个代理列表proxy_list,然后在start_requests方法中,为每个请求设置不同的代理,从而实现代理轮换。

    此外,Crawlee还具备类人指纹生成功能,它能够模拟真实用户的浏览器指纹,包括浏览器类型、版本、操作系统等信息,使爬虫的行为更加接近真实用户,从而降低被反爬虫机制检测到的概率。在使用Crawlee时,这些功能默认是开启的,无需额外配置,为我们提供了极大的便利。

    分布式爬虫部署

    随着数据量的不断增长和爬虫任务的日益复杂,单机爬虫的性能可能会受到限制。为了提高抓取效率,Crawlee支持分布式爬虫部署,允许我们将爬虫任务分布到多个节点上并行执行。通过分布式部署,我们可以充分利用多台机器的计算资源,大大加快数据抓取的速度,同时也提高了爬虫系统的稳定性和可靠性。虽然分布式爬虫部署的配置相对复杂,但Crawlee提供了相关的文档和工具,帮助开发者快速搭建分布式爬虫环境。对于有大规模数据抓取需求的读者来说,分布式爬虫部署是一个值得深入研究和实践的方向,它能够为数据采集工作带来更高的效率和更大的灵活性。

    五、总结

    Crawlee作为一款功能强大、灵活易用的下一代网络爬虫与浏览器自动化工具,在数据抓取领域展现出了巨大的优势。它不仅具备强大的抓取能力,能够应对各种复杂的网页结构和反爬虫机制,还提供了简洁高效的编程接口,使得开发者能够轻松实现数据爬取和浏览器自动化操作。通过使用Crawlee,我们可以高效地获取网络数据,为数据分析、机器学习等任务提供有力的数据支持。

    对于广大开发者来说,Crawlee无疑是一个值得尝试的工具。无论你是初涉爬虫领域的新手,还是经验丰富的爬虫开发者,Crawlee都能为你带来全新的体验和便利。它丰富的功能和活跃的社区,将助力你在爬虫开发的道路上不断前行,实现更多的创意和想法。

    欢迎大家在留言区分享自己使用Crawlee的经验和心得,一起探索爬虫技术的无限可能。

    六 、参考资料

    1.Github链接(Javascript):https://github.com/apify/crawlee
    2.Github链接(Python)https://github.com/apify/crawlee-python
    3.Python使用教程链接:https://crawlee.dev/python/docs/quick-start
    4.Javascript使用教程链接:https://crawlee.dev/js/docs/quick-start

     


    如果你觉得这篇文章还不错,不妨动动手指,给它点个赞?,让更多人看到它的魅力。觉得内容对你有帮助,就大胆地分享到朋友圈吧,让知识传递得更远。同时,也欢迎在评论区留下你的想法和见解,我们一起交流探讨。当然,别忘了关注我,这样你就不会错过我后续的精彩分享啦!最后,记得点个“在看”?,让我们共同见证测试之美!


    •(END)•

    如有任何疑问,点击添加【个人微信】咨询!

    喜欢这篇文章欢迎转发、分享朋友圈~


    目前100000+人已关注我们

           

           



    接口自动化测试系列


    UI自动化测试系列


    自动化测试系列


    抓包工具系列


    功能测试系列


    面试宝典系列


    测试工具系列


    团队管理系列


    性能测试系列


    引导三连.jpg

    53AI,企业落地大模型首选服务商

    产品:场景落地咨询+大模型应用平台+行业解决方案

    承诺:免费场景POC验证,效果验证后签署服务协议。零风险落地应用大模型,已交付160+中大型企业

    联系我们

    售前咨询
    186 6662 7370
    预约演示
    185 8882 0121

    微信扫码

    添加专属顾问

    回到顶部

    加载中...

    扫码咨询