教你使用Python爬取网站图片

今天给大家带来一个Python代码,可以自动爬取网站的图片。

这个脚本是我自己的一个练手爬虫,如果你要使用此代码,请遵守国家的法规,不要在未经允许的情况下非法爬取其他网站的图片。

这段代码是一个用于从指定网页下载图片的爬虫程序。要使用该程序,需要在命令行中指定要爬取的网页URL和保存图片的文件夹名。

使用本代码 首先将它保存到<文件名>.py文件中,请自行命名。假设你有一个名为images的文件夹,你想要从https://example.com这个网页中下载所有的图片,并保存到该文件夹中。

在文件夹中按住shift键并用鼠标右键点击空白处,选择在此处打开PowerShell窗口,复制以下代码:


python .py --url https://example.com --folder images

请注意:<文件名>请替换为你的py文件名,https://example.com请替换你想要爬取的网站地址,images替换为你想要保存的文件夹名

回车即可运行,如果你成功运行,应该会输出得到下图这样的内容。

由于我在Python代码中自动过滤了10KB以下的图片和3MB以上的图片,如果需要关闭过滤,请在代码中自行修改。

以下是Python代码:


import os
import sys
sys.stdout.reconfigure(encoding='utf-8')
import argparse
import requests
from bs4 import BeautifulSoup
from urllib.parse import urljoin
from tqdm import tqdm
from concurrent.futures import ThreadPoolExecutor
from requests.exceptions import Timeout

# 创建命令行参数解析器
parser = argparse.ArgumentParser(description='Download images from a webpage.')
parser.add_argument('--url', required=True, help='URL of the webpage to scrape images from')
parser.add_argument('--folder', required=True, help='Folder name to save downloaded images')
args = parser.parse_args()

# 从命令行参数中获取 URL 和 folder_name
url = args.url
folder_name = args.folder

# 发起请求
try:
    response = requests.get(url, timeout=20)  # 设置超时时间为20秒
    response.raise_for_status()
except Timeout:
    print("请求超时,无法获取页面内容")
    exit()

# 使用BeautifulSoup解析网页内容
soup = BeautifulSoup(response.content, 'html.parser')

# 动态文件夹路径
if not os.path.exists(folder_name):
    os.makedirs(folder_name)

# 查找所有图片标签
img_tags = soup.find_all('img')

# 下载图片的函数
def download_image(img_url, index):
    try:
        img_response = requests.get(img_url, timeout=60)  # 设置超时时间为60秒
        img_response.raise_for_status()
    except Timeout:
        print(f"图片 {img_url} 下载超时,跳过")
        return None
    except requests.exceptions.HTTPError as e:
        print(f"图片 {img_url} 下载失败: {e.response.status_code}, 跳过")
        return None
    img_data = img_response.content
    img_size = len(img_data)

    # 限制只保存小于3MB且大于50KB的图片
    if img_size > 3 * 1024 * 1024:
        print(f"图片 {img_url} 大于3MB,跳过下载")
        return None
    if img_size < 10 * 1024:
        print(f"图片 {img_url} 小于10KB,跳过下载")
        return None

    img_name = f"{folder_name}({index-1})"  # 使用自定义的文件名,例如 "图片 0"
    img_path = os.path.join(folder_name, f"{img_name}.jpg")  # 保存为jpg格式

    # 检查图片是否已经存在,避免重复下载
    if os.path.exists(img_path):
        print(f"图片 {img_name} 已存在,跳过下载")
        return None

    # 使用tqdm显示进度条
    with tqdm(total=100, desc=f"下载 {img_name}", unit="%") as pbar:
        with open(img_path, 'wb') as img_file:
            for chunk in img_response.iter_content(chunk_size=1024):
                if chunk:
                    img_file.write(chunk)
                    pbar.update(len(chunk) * 100 / img_size)

    return img_name

# 使用线程池进行并发下载
with ThreadPoolExecutor(max_workers=10) as executor:
    downloaded_images = list(
        tqdm(
            executor.map(download_image, [urljoin(url, img_tag.get('src')) for img_tag in img_tags], range(len(img_tags))),
            total=len(img_tags),
            desc="下载进度",
            unit="张"
        )
    )

# 打印已下载的图片信息
downloaded_images = [img_name for img_name in downloaded_images if img_name is not None]
print(f'共下载 {len(downloaded_images)} 张图片')
print('图片爬取和保存完成!')

这段代码使用了以下Python库:

  1. argparse: 用于解析命令行参数。
  2. BeautifulSoup: 用于解析HTML内容。
  3. requests: 用于发送HTTP请求。
  4. tqdm: 用于在命令行中显示进度条。
  5. concurrent.futures.ThreadPoolExecutor: 用于实现并发下载。
  6. urllib.parse.urljoin: 用于拼接URL。

如果你没有安装这些库,你可以自行安装,这篇文章不做Python库安装教程展开。

Leave a Comment

您的电子邮箱地址不会被公开。 必填项已用*标注