Python爬虫中的并发编程详解

yizhihongxing

Python爬虫中的并发编程详解

在Python爬虫中,为了提高爬虫效率,通常需要使用并发编程。本文将介绍Python爬虫中的并发编程,包括多线程、协程和异步IO等技术。同时,还会提供两个示例讲解。

多线程

多线程是指在一个进程中存在多个线程,每个线程都可以独立执行不同的任务。在Python中,可以使用threading模块实现多线程编程。

下面是一个简单的示例,使用多线程爬取多个网页内容:

import threading
import requests

urls = ['https://www.baidu.com', 'https://www.hao123.com', 'https://www.sogo.com']

def fetch(url):
    response = requests.get(url)
    print(url, response.status_code)

threads = []
for url in urls:
    t = threading.Thread(target=fetch, args=(url,))
    threads.append(t)

for t in threads:
    t.start()

for t in threads:
    t.join()

在上述示例中,首先定义了一个fetch函数,用于发送HTTP请求并打印响应状态码。然后定义了一个urls列表,其中包含要爬取的网页地址。接着,使用threading.Thread类创建多个线程,并将它们添加到threads列表中。最后,分别启动所有线程并等待它们执行完成。

协程

协程是一种更轻量级的线程,由于不需要线程上下文切换的开销,因此协程的并发量通常比多线程要高。在Python中,可以使用asyncio模块实现协程编程。

下面是一个简单的示例,使用协程爬取多个网页内容:

import asyncio
import aiohttp

urls = ['https://www.baidu.com', 'https://www.hao123.com', 'https://www.sogo.com']

async def fetch(url):
    async with aiohttp.ClientSession() as session:
        async with session.get(url) as response:
            print(url, response.status)

async def main():
    tasks = [fetch(url) for url in urls]
    await asyncio.gather(*tasks)

asyncio.run(main())

在上述示例中,首先定义了一个fetch协程函数,使用aiohttp库发送HTTP请求并打印响应状态码。然后定义了一个urls列表,其中包含要爬取的网页地址。接着,使用asyncio.gather()函数将多个协程任务合并为一个main协程任务,并使用asyncio.run()函数运行它。

异步IO

异步IO是一种高效的IO模型,它允许程序在等待IO操作完成时执行其他任务。在Python中,可以使用asyncio模块实现异步IO编程。

下面是一个简单的示例,使用异步IO爬取多个网页内容:

import asyncio
import aiohttp

urls = ['https://www.baidu.com', 'https://www.hao123.com', 'https://www.sogo.com']

async def fetch(url):
    async with aiohttp.ClientSession() as session:
        async with session.get(url) as response:
            return await response.text()

async def main():
    tasks = [fetch(url) for url in urls]
    responses = await asyncio.gather(*tasks)
    for url, response in zip(urls, responses):
        print(url, len(response))

asyncio.run(main())

在上述示例中,首先定义了一个fetch协程函数,使用aiohttp库发送HTTP请求并返回响应内容。然后定义了一个urls列表,其中包含要爬取的网页地址。接着,使用asyncio.gather()函数将多个协程任务合并为一个main协程任务,并使用asyncio.run()函数运行它。最后,将每个网页的URL和响应内容长度打印出来。

示例说明

示例1:使用多线程下载图片

假设需要从多个网站下载图片,为了提高下载速度,可以使用多线程进行并发下载。可以定义一个download函数用于下载图片,然后使用多线程启动多个download函数进行下载。

import requests
import threading

urls = [
    'https://www.baidu.com/img/PCfb_5bf082d29588c07f842ccde3f97243ea.png',
    'https://www.hao123.com/static/img/newindex/logo_efe5aabd.png',
    'https://www.sogou.com/images/logo/new/sogou.png'
]

def download(url):
    response = requests.get(url)
    filename = url.split('/')[-1]
    with open(filename, 'wb') as f:
        f.write(response.content)
    print(f'{url}下载完成')

threads = []
for url in urls:
    t = threading.Thread(target=download, args=(url,))
    t.start()
    threads.append(t)

for t in threads:
    t.join()

在上述示例中,首先定义了一个download函数,用于下载指定URL的图片,并将其保存到本地文件。然后定义了一个urls列表,其中包含要下载的图片URL。接着,使用多线程启动多个download函数进行下载,并等待所有线程执行完成。

示例2:使用协程爬取豆瓣电影Top250

假设需要爬取豆瓣电影Top250页面,并获取每部电影的名称、评分和简介。可以先分析页面结构,然后使用aiohttpasyncio库进行异步IO爬取。

import aiohttp
import asyncio
from lxml import etree

async def fetch(session, url):
    async with session.get(url) as response:
        return await response.text()

async def parse(html):
    tree = etree.HTML(html)
    items = tree.xpath('//div[@class="info"]')
    for item in items:
        title = item.xpath('.//span[@class="title"]/text()')[0]
        rating = item.xpath('.//span[@class="rating_num"]/text()')[0]
        desc = item.xpath('.//span[@class="inq"]/text()')[0]
        print(f'{title}{rating}  {desc}')

async def main():
    async with aiohttp.ClientSession() as session:
        for i in range(0, 250, 25):
            url = f'https://movie.douban.com/top250?start={i}&filter='
            html = await fetch(session, url)
            await parse(html)

asyncio.run(main())

在上述示例中,首先定义了一个fetch协程函数,使用aiohttp库发送HTTP请求并返回响应内容。然后定义了一个parse协程函数,使用lxml库解析HTML页面,并提取电影名称、评分和简介等信息。接着,使用asyncio.gather()函数将多个协程任务合并为一个main协程任务,并使用asyncio.run()函数运行它。最后,根据豆瓣电影Top250页面的分页规则,循环下载每一页的HTML并解析获取电影信息。

以上是Python爬虫中的并发编程详解过程,包括多线程、协程和异步IO等技术,并提供了两个示例说明。理解并掌握这些技术,可以提高爬虫效率,缩短爬取时间。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Python爬虫中的并发编程详解 - Python技术站

(1)
上一篇 2023年5月14日
下一篇 2023年5月14日

相关文章

  • python3 pillow生成简单验证码图片的示例

    下面是“python3 pillow生成简单验证码图片的示例”完整攻略: 一、前置知识 在学习本文之前,需要先了解以下知识: Python3基础知识 Python3的Pillow库 二、正文 1. 安装Pillow库 Pillow库是Python中用于图像处理的重要库之一,可以通过pip命令简单安装: pip install pillow 2. 生成简单验证…

    python 2023年6月3日
    00
  • 在 Python 中,如何从另一个未在本地导入的文件中修补函数?

    【问题标题】:In Python, how can I patch a function from another file that’s not imported locally?在 Python 中,如何从另一个未在本地导入的文件中修补函数? 【发布时间】:2023-04-03 15:39:01 【问题描述】: 我正在学习 Pythonic 测试开发,偶…

    Python开发 2023年4月8日
    00
  • Python网页解析利器BeautifulSoup安装使用介绍

    BeautifulSoup库介绍 BeautifulSoup是一个Python库,用于从HTML和XML文件中提取数据。它可以解析HTML和XML文件,并提供了一些方便的方法来查找和操作数据。BeautifulSoup库可以帮助我们快速地从网页中提取所需的信息,是Python中最常用的网页解析库之一。 安装BeautifulSoup库 在使用Beautifu…

    python 2023年5月14日
    00
  • python超详细实现完整学生成绩管理系统

    Python超详细实现完整学生成绩管理系统 系统概述 本系统是一个基于Python的学生成绩管理系统,能够方便地记录学生的基本信息,并可以录入和查询学生的各科成绩情况。该系统主要包括三个模块,分别是学生信息管理模块、成绩录入模块和成绩查询模块。具体实现依赖于Python基础知识和面向对象编程的概念。 功能模块介绍 学生信息管理模块 学生基本信息录入; 学生基…

    python 2023年5月19日
    00
  • python中os.path.join()函数实例用法

    下面是关于“python中os.path.join()函数实例用法”的详细攻略: 1. 什么是os.path.join()函数? 在Python中,os.path.join()是用来组合路径的函数,你可以使用它来构造跨操作系统的文件路径。这个函数会根据当前的操作系统来调整路径分隔符。 当你在Windows中使用/作为分隔符时,在Linux中使用\作为分隔符时…

    python 2023年5月14日
    00
  • Python密码学XOR算法编码流程及乘法密码教程

    标题:Python密码学XOR算法编码及乘法密码教程 XOR算法编码流程 1.输入明文和密钥。 2.将明文和密钥转化为二进制。 3.将明文和密钥按位异或。若明文和密钥同一位为0或1,则异或结果为0,否则为1。 4.将异或后的结果转化为十六进制,即为密文。 示例1: 明文:hello 密钥:world 1.明文和密钥转化为二进制为: hello:0110100…

    python 2023年5月31日
    00
  • Python处理session的方法整理

    在Python中处理session是非常常见的任务。本文将介绍如何处理session,并提供两个示例。 1. 使用requests库处理session 在Python中处理session可以使用requests库。requests是一个Python HTTP库,可以轻松发送HTTP请求。以下是一个示例,演示如何使用requests处理session: imp…

    python 2023年5月15日
    00
  • python实现根据窗口标题调用窗口的方法

    下面是 “python实现根据窗口标题调用窗口的方法” 的完整攻略。 1. 安装所需库 在Python中操作窗口需要使用pywin32库,需要先安装该库。 可以使用pip命令来安装pywin32库。 pip install pywin32 2. 获取窗口句柄 我们需要先获取我们需要操作的窗口的句柄,通过调用FindWindow函数,语法如下: import …

    python 2023年5月20日
    00
合作推广
合作推广
分享本页
返回顶部