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

Playwright进行异步爬取案例

时间:2024-11-22 16:45:02浏览次数:3  
标签:异步 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

相关文章

  • [python] Python异步编程库asyncio使用指北
    Python的asyncio模块提供了基于协程(coroutines)的异步编程(asynchronousprogramming)模型。作为一种高效的编程范式,异步编程允许多个轻量级任务并发执行,且相比传统的多线程模型,具有更低的内存消耗。因此,asyncio在需要高并发处理的场景中,尤其是在Web开发、网络请求、API调用和套接字......
  • Python网络爬虫实践案例:爬取猫眼电影Top100
    以下是一个Python网络爬虫的实践案例,该案例将演示如何使用Python爬取猫眼电影Top100的电影名称、主演和上映时间等信息,并将这些信息保存到TXT文件中。此案例使用了requests库来发送HTTP请求,使用re库进行正则表达式匹配,并包含详细的代码解释,以确保代码可以直接运行。1.准备工作......
  • 电影影片数据爬取与数据可视化分析Python毕设源码论文Django,VUE
        博主介绍:......
  • 深入理解 Callable 和 Future:异步编程的强大工具
    在多线程编程中,Callable和Future提供了一种强大的方式来处理异步任务,它们解决了Runnable无法返回结果以及无法处理异常的问题。通过Callable和Future,你可以实现更加高效和灵活的线程管理。本篇博客将详细探讨Callable与Runnable的区别,Future的作用以及如何利用这......
  • 异步编程在ArkTS中具体怎么实现?
    大家好,我是V哥,很好奇,在ArkTS中实现异步编程是怎样的,今天的内容来聊聊这个问题,总结了一些学习笔记,分享给大家,在ArkTS中实现异步编程主要可以通过以下几种方式:1.使用async和await关键字async函数是一种特殊的函数,它能以同步代码的方式编写异步代码。在async函数内部,可以使用aw......
  • 爬取网易云音乐热歌榜:从入门到实战
    爬取网易云音乐热歌榜:从入门到实战前提声明爬虫应遵守目标网站的robots.txt协议,尊重版权和用户隐私。本代码仅供学习和研究使用,不得用于商业用途。请确保在合法合规的前提下使用本代码。本代码所爬音乐为公开可选择的音乐目录引言环境准备代码结果代码解析1.榜单ID与......
  • Python爬取国家统计局数据按行业分国有单位就业人员数据
    Python爬取国家统计局数据按行业分国有单位就业人员数据0、前言国家数据,慎爬!!!因开发需要获取国家统计局数据-按行业分国有单位就业人员数据,特整理此代码用于抓取国家统计局数据按行业分国有单位就业人员数据。1、数据来源数据来源于国家统计局2、python代码importpa......
  • 《刚刚问世》系列初窥篇-Java+Playwright自动化测试-5-创建首个自动化脚本(详细教程)
    1.简介前面几篇宏哥介绍了两种(java和maven)环境搭建和浏览器的启动方法,这篇文章宏哥将要介绍第一个自动化测试脚本。前边环境都搭建成功了,浏览器也驱动成功了,那么我们不着急学习其他内容,首先宏哥搭建好的环境中创建首个完整的自动化测试脚本,让小伙伴或者童鞋们提前感受感受,也是为......
  • 模拟线程池与异步方法调用查询接口优化
    问题:批量查询如何优化?entity实体类packagecom.itheima.alipay.prop;importlombok.Data;@DatapublicclassUserInfo{privateLonguserId;privateStringusername;privateintage;publicUserInfo(LonguserId,Stringusername,intage){......
  • Abp.VNext-异步执行帮助类AsyncHelper
    作用以同步的方式运行异步方法。代码实现//无返回值的异步方法publicasyncTaskGetDataNoResult(){awaitTask.CompletedTask;}//有返回值的异步方法publicasyncTask<bool>GetDataWithResult(){returnawaitTask.FromResult(true);}[Htt......