达永编程网

程序员技术分享与交流平台

JavaScript的迭代器与生成器,如何让你的数据遍历酷到没朋友!

嘿,朋友们!在你的编程生涯中,有没有遇到过这样的“烦恼”?当你面对一个庞大的数据集,比如几百万条用户记录,或者是一个永无止境的数据流(想象一下实时日志、传感器数据),你是不是还在习惯性地使用

[3]Python高级特性-【1】生成器

生成器是Python中非常强大且重要的概念,它允许你在迭代中生成值而不需要显式地创建一个完整的列表。生成器通常在处理大量数据时非常有用,因为它可以节省大量的内存和处理时间。在本教程中,我们将深入探讨Python中的生成器及其使用方法。

Python编程:如何搞定生成器(Generator)及表达式?来盘它

前言

在前面的篇章中,我们学习了迭代器,这是一个很好的工具,特别是当你需要处理大型数据集时。然而,在Python中构建自己的迭代器有点麻烦和耗时。你必须定义一个实现迭代器协议(__iter__()和__next__()方法)的新类。在这个类中,需要自己管理变量的内部状态并更新它们。此外,当__next__()方法中没有要返回的值时,需要抛出StopIteration异常。

async/await原理以及手写async函数

在 JavaScript 中,async/await 是处理异步操作的语法糖,其底层基于

MEMO的存储证明流程

互联网中存在大量的边缘存储设备,MEMO通过对这种闲置资源的整合搭建了一个可扩展的分散式云存储协议,使存储资源有限的用户可将数据存储在边缘存储节点上。但是在这样一个公开的低可信环境中,边缘存储节点可靠性较低,他们可能会作出篡改、删除数据等恶意行为,因此需要对存储节点进行有效监督,以验证他们是否正确地持有存储数据。

Python生成器详解 | 投稿

程派微信号:codingpy

本文为作者、kissg.me博主赵喧典授权编程派原创发布。文章比较长,大家可以收藏了慢慢看哈~~

引文

编程派前几天推送了一篇文章,叫“Python学习进阶路线(简版)”,生成器(generator)赫然在列.可是我不太会.不会怎么办?学咯。于是上网看了不少教程,又看了官方文档,学到了不少知识。在此,权且做个学习笔记,也与大家分享一下。

5分钟掌握Python(八)之生成器

1)说明:在 Python 中,这种一边循环一边计算的机制,称为生成器:generator。在 Python 中,使用了 yield 的函数被称为生成器(generator)。跟普通函数不同的是,生成器是一个返回迭代器的函数,只能用于迭代操作,更简单点理解生成器就是一个迭代器。在调用生成器运行的过程中,每次遇到 yield 时函数会暂停并保存当前所有的运行信息,返回 yield 的值。并在下一次执行 next()方法时从当前位置继续运行。

爬取“https://ssr1.scrape.center”的爬虫

# 导入所需库
import requests  # 用于发送HTTP请求
import logging  # 用于记录日志
import re  # 用于正则表达式匹配
from urllib.parse import urljoin  # 用于拼接URL
import json  # 用于JSON数据处理
from os import makedirs  # 创建目录
from os.path import exists  # 检查路径是否存在
import multiprocessing  # 用于多进程处理


# 基础URL和总页数常量
BASE_URL = 'https://ssr1.scrape.center'  # 目标网站根URL
TOTAL_PAGE = 10  # 需要爬取的总页数

# 定义一个用于保存爬取结果的目录名,所有 JSON 文件将保存在这个文件夹中
RESULTS_DIR = 'results'

# 如果该目录不存在,则创建它(避免手动提前建目录)
# 使用短路逻辑:如果 exists(RESULTS_DIR) 为 False,就会执行 makedirs(RESULTS_DIR)
exists(RESULTS_DIR) or makedirs(RESULTS_DIR)


def save_data(data):
    """保存数据到JSON文件"""
    name = data.get('name')  # 从数据中获取电影名称作为文件名
    data_path = f'{RESULTS_DIR}/{name}.json'  # 构建文件路径
    # 写入JSON文件(确保非ASCII字符正常显示)
    json.dump(data, open(data_path, 'w', encoding='utf-8'),
              ensure_ascii=False, indent=2)

# 配置日志格式和级别
logging.basicConfig(
    level=logging.INFO,  # 设置日志级别为INFO
    format='%(asctime)s-%(levelname)s:%(message)s'  # 日志格式:时间-级别-消息
)


def scrape_page(url):
    """通用页面爬取函数"""
    logging.info('scraping %s...', url)
    try:
        response = requests.get(url)  # 发送GET请求
        if response.status_code == 200:  # 如果响应成功
            return response.text  # 返回HTML内容
        # 记录错误状态码
        logging.error('get invalid status code %s while scraping %s', 
                      response.status_code, url)
    except requests.RequestException:
        # 记录请求异常信息(包含堆栈跟踪)
        logging.error('error occurred while scraping %s', url, exc_info=True)

def scrape_index(page):
    """列表页爬取函数"""
    index_url = f'{BASE_URL}/page/{page}'  # 构造列表页URL
    return scrape_page(index_url)  # 调用通用爬取方法

def parse_index(html):
    """解析列表页HTML,提取详情页URL"""
    pattern = re.compile('<a.*?href="(.*?)".*?class="name">')  # 匹配详情页链接的正则
    items = re.findall(pattern, html)  # 查找所有匹配项
    if not items:
        return []  # 无匹配返回空列表
    for item in items:
        detail_url = urljoin(BASE_URL, item)  # 拼接完整URL
        logging.info('get detail url %s', detail_url)
        yield detail_url  # 生成器逐个返回URL

def scrape_detail(url):
    """详情页爬取函数(直接复用通用爬取)"""
    return scrape_page(url)

def parse_detail(html):
    """解析详情页HTML,提取电影信息"""
    # 定义各类信息的正则表达式模式
    cover_pattern = re.compile('class="item".*?<img.*?src="(.*?)".*?class="cover">', re.S)
    name_pattern = re.compile('<h2.*?>(.*?)</h2>')
    categories_pattern = re.compile('<button.*?category.*?<span>(.*?)</span>.*?</button>', re.S)
    published_at_pattern = re.compile('(\d{4}-\d{2}-\d{2})\s?上映')
    drama_pattern = re.compile('<div.*?drama.*?>.*?<p.*?>(.*?)</p>', re.S)
    score_pattern = re.compile('<p.*?score.*?>(.*?)</p>', re.S)
    
    # 提取并处理各项数据(处理可能的匹配失败)
    cover = re.search(cover_pattern, html).group(1).strip() if re.search(cover_pattern, html) else None
    name = re.search(name_pattern, html).group(1).strip() if re.search(name_pattern, html) else None
    categories = re.findall(categories_pattern, html) if re.findall(categories_pattern, html) else []
    published_at = re.search(published_at_pattern, html).group(1) if re.search(published_at_pattern, html) else None
    drama = re.search(drama_pattern, html).group(1).strip() if re.search(drama_pattern, html) else None
    score = float(re.search(score_pattern, html).group(1).strip()) if re.search(score_pattern, html) else None
    
    # 返回结构化数据字典
    return {
        'cover': cover,          # 封面图URL
        'name': name,            # 电影名称
        'categories': categories, # 分类标签列表
        'published_at': published_at,  # 上映日期
        'drama': drama,          # 剧情简介
        'score': score           # 评分(浮点数)
    }

def main(page):
    """主处理函数(单个页面的处理流程)"""
    index_html = scrape_index(page)  # 爬取列表页
    detail_urls = parse_index(index_html)  # 解析详情页URL
    for detail_url in detail_urls:
        detail_html = scrape_detail(detail_url)  # 爬取详情页
        data = parse_detail(detail_html)  # 解析详情页数据
        logging.info('get detail data %s', data)
        logging.info('saving data to json data')
        save_data(data)  # 保存数据到文件
        logging.info('data saved successfully')

if __name__ == '__main__':
    """多进程执行入口"""
    pool = multiprocessing.Pool()  # 创建进程池
    pages = range(1, TOTAL_PAGE + 1)  # 生成页码列表 (1-10)
    pool.map(main, pages)  # 多进程并行处理所有页面
    pool.close()  # 关闭进程池(停止添加新任务)
    pool.join()  # 等待所有子进程完成

Python进阶-Day6:迭代器与生成器

一、基础概念

1. 什么是迭代器?

  • 定义:迭代器是一个能记住遍历位置的"智能指针"
  • 特征: 通过 next() 获取下一个值 遍历结束后会触发 StopIteration 异常 只能前进不能后退

Python生成器

一、Python生成器介绍

1.什么是生成器

在Python中,使用了

<< 1 2 > >>
控制面板
您好,欢迎到访网站!
  查看权限
网站分类
最新留言