首页 > 其他分享 >Playwright进行异步爬取案例

Playwright进行异步爬取案例

时间:2024-11-24 17:28:58浏览次数:9  
标签:异步 Playwright score url await 爬取 tag data page

1.代码功能概述

该代码使用 Playwright 异步库编写,用于抓取一个目标网站的数据。主要任务包括:

  1. 加载网页:访问指定页面并等待加载完成。
  2. 解析网页内容:提取数据如标题、封面图片、分类、评分、简介等。
  3. 存储数据:将抓取到的数据以特定格式保存到本地文件中。

2.代码结构解析

1. 导入模块

import asyncio
import logging
from os.path import exists
from playwright.async_api import async_playwright
from urllib.parse import urljoin
  • asyncio:用于异步操作。
  • logging:用于记录程序的运行日志。
  • os.path.exists:检查指定路径是否存在。
  • async_playwright:Playwright 异步版本,用于浏览器自动化。
  • urljoin:用于拼接相对路径和基准路径,生成完整的 URL。

2. 全局变量与初始化

logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s: %(message)s')
BASE_URL = 'https://ssr1.scrape.center'
TOTAL_PAGE = 2
RESULT_DIR = 'data'
exists(RESULT_DIR) or makedirs(RESULT_DIR)
  • 设置日志记录格式和级别。
  • 定义爬取的目标网站的基本 URL (BASE_URL) 和总页数 (TOTAL_PAGE)。
  • RESULT_DIR:存储数据的目录。
  • 如果结果存储目录不存在,则创建该目录。

3. 页面加载功能

async def scrape_page(page, url):
    logging.info('scraping %s ...', url)
    try:
        await page.goto(url)  # 跳转到目标 URL
        await page.wait_for_load_state('networkidle')  # 等待页面完全加载
    except Exception as e:
        logging.error(f"Error scraping {url}: {str(e)}", exc_info=True)
        return False
    return True
  • 功能:访问指定的网页 URL,等待其加载完成。
  • 异常处理:如果加载失败,记录错误并返回 False

4. 索引页和详情页抓取功能

async def scrape_index(page, page_index):
    index_url = f'{BASE_URL}/page/{page_index}'
    return await scrape_page(page, index_url)

async def scrape_detail(page, url):
    return await scrape_page(page, url)
  • scrape_index:访问分页列表页。
  • scrape_detail:访问详情页。

5. 索引页内容解析

async def parse_index(page):
    elements = await page.query_selector_all('a.name')  # 找到所有目标链接
    for element in elements:
        part_of_url = await element.get_attribute('href')  # 获取链接地址
        if part_of_url:
            detail_url = urljoin(BASE_URL, part_of_url)  # 拼接完整 URL
            logging.info('get url: %s', detail_url)
            yield detail_url
  • 查找页面中所有指定的 <a> 标签,并提取其 href 属性。
  • 通过 urljoin 拼接为完整的详情页 URL。

6. 详情页内容解析

async def parse_detail(page):
    name_tag = await page.query_selector('h2.m-b-sm')
    name = await name_tag.text_content() if name_tag else None

    cover_tag = await page.query_selector('img.cover')
    cover = await cover_tag.get_attribute('src') if cover_tag else None

    category_tags = await page.query_selector_all('div.categories > button > span')
    categories = [await category.text_content() for category in category_tags] if category_tags else []

    score_tag = await page.query_selector('p.score')
    score = await score_tag.text_content().strip() if score_tag else None

    drama_tag = await page.query_selector('div.drama > p')
    drama = await drama_tag.text_content().strip() if drama_tag else None

    return {
        'name': name,
        'cover': cover,
        'categories': categories,
        'drama': drama,
        'score': score
    }
  • 使用 CSS 选择器提取以下内容:
    • 标题h2.m-b-sm
    • 封面图片链接img.cover
    • 分类div.categories > button > span
    • 评分p.score
    • 简介div.drama > p
  • 每个字段都有空值检查,避免因元素缺失导致错误。

7. 数据存储

async def save_data(data):
    data_path = '{0}/movies_selector_async.txt'.format(RESULT_DIR)
    with open(data_path, 'w', encoding='utf-8') as file:
        name = data.get('name', None)
        cover = data.get('cover', None)
        categories = data.get('categories', None)
        drama = data.get('drama', None)
        score = data.get('score', None)

        file.write('name:'+name+'\n')
        file.write('cover:'+cover+'\n')
        file.write('categories:'+str(categories)+'\n')
        file.write('drama:'+drama+'\n')
        file.write('score:'+score+'\n')
        file.write('='*50 + '\n')
  • 数据格式化后写入文件,采用 key:value 格式,并用分隔线分隔。

8. 主函数

async def main():
    logging.info("开始采集")
    playwright = await async_playwright().start()
    browser = await playwright.chromium.launch(headless=True)
    context = await browser.new_context()
    page_1 = await context.new_page()
    page_num = 3
    flag = 0

    for i in range(1, page_num):
        url = "https://spa6.scrape.center/page/"+str(i)
        await page_1.goto(url)
        await page_1.wait_for_load_state('networkidle')
        elements = await page_1.query_selector_all('div.el-card.item.m-t.is-hover-shadow')

        page_2 = await context.new_page()
        for element in elements:
            logging.info("子页面采集开始")
            tag_a = await element.query_selector('a')
            detail_url = 'https://spa6.scrape.center' + await tag_a.get_attribute('href')
            await scrape_detail(page_2, detail_url)
            data = await parse_detail(page_2)
            logging.info('get data: %s', data)
            await save_data(data)
            logging.info("子页面采集结束")
            flag = flag+1

    logging.info("全部数据采集结束,共:{}条".format(flag))
    await browser.close()
  • 打开浏览器并创建上下文与页面。
  • 遍历分页,提取每页的所有详情链接并依次访问。
  • 调用解析函数提取数据并保存。
    在这里插入图片描述

标签:异步,Playwright,score,url,await,爬取,tag,data,page
From: https://blog.csdn.net/zkw54334/article/details/143910704

相关文章

  • 一分钟了解同步与异步时序逻辑电路
    在同步时序电路中,各触发器的时钟端全部连接到同一个时钟源上,只有当时钟脉冲到来时,电路的状态才能改变。(注意不要求是同一时钟,而是同源时钟。所谓的同源时钟是指同一个时钟源衍生频率比值为2的幂次方,且初相位相同的时钟。)同步逻辑是指时钟之间有固定的因果......
  • 【前端知识】JS实现异步编程
    JS异步编程一、JS异步编程的背景和重要性二、JS异步编程的实现方式三、JS异步编程的示例四、JS异步编程中的错误处理五、JS异步编程的优势JS异步编程是一种编程范式,它允许程序在等待某些操作完成(如I/O操作、网络请求等)时,不必阻塞当前执行线程,而是可以继续执行其他任......
  • windows C#-异步文件访问
    可使用异步功能访问文件。通过使用异步功能,你可以调用异步方法而无需使用回调,也不需要跨多个方法或lambda表达式来拆分代码。若要使同步代码异步,只需调用异步方法而非同步方法,并向代码中添加几个关键字。可能出于以下原因向文件访问调用中添加异步:异步使UI应用程序响应......
  • WPF异步UI交互功能的实现方法
    前面的文章我们提及过,异步UI的基础实现。基本思路主要是开启新的UI线程,并通过VisualTarget将UI线程上的Visual(即RootVisual)连接到主线程上的UI上即可渲染显示。但是,之前的实现访问是没有交互能力的,视觉树上的UI并不能实现鼠标事件。那么今天我们就把交互的工作也给完成了。......
  • JS异步编程精通之路(一):Callback、Promise、Async/Await 和 Observable 深度对比
    在现代JavaScript编程中,异步操作是常见且必不可少的部分。处理异步的方式多种多样,其中最常见的有Callback、Promise、Async/Await,以及近年来随着响应式编程(ReactiveProgramming)理念兴起的Observable。本文将对这几种异步处理方式进行对比,帮助你理解它们各自的优缺点,以......
  • 使用Python异步抓取豆瓣电影数据并进行可视化
    一前言在本篇文章中,我们将探讨如何使用Python的asyncio和aiohttp库来异步抓取豆瓣电影Top250中的电影数据,并将这些数据保存到CSV文件中,最后使用matplotlib库对评分趋势进行可视化。目标网站:https://movie.douban.com/top250二环境准备首先确保你的环境中已经安装了......
  • RabbitMQ 入门(一)同步通讯和异步通讯
    一、同步通讯和异步通讯微服务间通讯有同步和异步两种方式:一)、同步通讯我们之前学习的Feign调用就属于同步方式,虽然调用可以实时得到结果,但存在下面的问题:同步调用的优点:-时效性较强,可以立即得到结果同步调用的问题:-耦合度高:每次加入新的需求,都要修改原来的代码;-性能......
  • 使用Python爬取免费代理并测试其有效性
    前言在本篇文章中,我们将使用Python编写一个脚本来爬取免费的代理IP地址,并对其进行有效性测试。我们将会用到playwright、aiohttp、pandas等库来完成这个任务。最终我们会得到一个包含有效代理IP地址的列表,并将其保存到本地文件中。1.环境准备首先,你需要确保你的Python环......
  • ubuntu20 运行playwright
    步骤pipinstallplaywrightplaywrightinstallplaywrightinstall-deps若弹出这个参考:https://www.cnblogs.com/code3/p/18458533解决tip但是貌似有2s的延迟。。......
  • Python如何创建异步上下文管理器
    异步上下文管理器的主要作用和使用场景:主要作用:自动管理异步资源的获取和释放确保异步操作的正确完成和清理简化异步代码的错误处理提供更清晰、更简洁的异步代码结构常见使用场景:数据库连接管理自动处理异步数据库连接的打开和关闭确保在操作完成后正确释......