网页图片爬虫

Admin
发布于 2026-05-25 / 2 阅读
0
0
import requests
import os
import time
from bs4 import BeautifulSoup
from urllib.parse import urljoin

headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36"
}

os.makedirs("wallpaper", exist_ok=True)

url = "https://weweclaw.com/"
res = requests.get(url, headers=headers)
# 自动推断编码,防止乱码
res.encoding = res.apparent_encoding

soup = BeautifulSoup(res.text, "html.parser")
imgs = soup.find_all("img")

for img in imgs:
    src = img.get("src")
    if not src:
        continue
    
    # 智能拼接URL,解决相对路径和绝对路径问题
    src = urljoin(url, src)
    
    try:
        img_data = requests.get(src, headers=headers, timeout=10).content
        file_name = src.split('/')[-1]
        # 防止文件名包含参数导致格式错误,简单取问号前的部分
        if '?' in file_name:
            file_name = file_name.split('?')[0]
            
        with open(f"wallpaper/{file_name}", "wb") as f:
            f.write(img_data)
        print(f"成功下载: {file_name}")
        
        # 礼貌爬取,避免被封IP
        time.sleep(0.5)
        
    except Exception as e:
        print(f"下载失败: {src}, 原因: {e}")

print("图片下载完成")

下面我将为你详细解释这段Python代码的含义、实现原理、用途以及需要注意的事项。

### 一、 代码含义与用途

这段代码是一个**网页图片爬虫**。它的主要功能是:访问指定的网站https://weweclaw.com/),解析该网页的HTML源码,提取出所有 <img> 标签中的图片链接,然后将这些图片下载并保存到本地名为 wallpaper 的文件夹中。

### 二、 实现原理与逐段解析

1. 导入必要的库

```python

import requests # 用于发送HTTP请求,获取网页内容和图片数据

import os # 用于操作本地文件系统(创建文件夹)

import time # 用于控制时间(休眠/延时)

from bs4 import BeautifulSoup # 用于解析HTML文档,提取所需标签

from urllib.parse import urljoin # 用于智能拼接URL

```

2. 设置请求头

```python

headers = {"User-Agent": "..."}

```

很多网站会反爬虫,拒绝没有浏览器标识的请求。这里设置了 User-Agent,伪装成Chrome浏览器发送请求,以绕过基础的反爬检测。

3. 创建本地保存目录

```python

os.makedirs("wallpaper", exist_ok=True)

```

在当前目录下创建 wallpaper 文件夹exist_ok=True 表示如果文件夹已存在则不报错,保证程序的健壮性。

4. 请求并解析网页

```python

res = requests.get(url, headers=headers)

res.encoding = res.apparent_encoding # 自动推断编码,防止乱码

soup = BeautifulSoup(res.text, "html.parser")

imgs = soup.find_all("img")

```

- 发送GET请求获取网页内容。

- res.apparent_encoding 使用 chardet 库自动推测网页编码,避免出现中文乱码。

- 使用 BeautifulSoup 将网页文本解析为树状结构,并找出所有的 <img> 标签。

5. 提取与处理图片链接

```python

src = img.get("src")

if not src: continue

src = urljoin(url, src)

```

- 获取 src 属性,如果为空则跳过。

- 核心技巧urljoin 用于处理相对路径。例如,如果提取到的 src/images/1.jpg,它会自动将其拼接为完整的绝对路径 https://weweclaw.com/images/1.jpg

6. 下载与保存图片

```python

img_data = requests.get(src, headers=headers, timeout=10).content

file_name = src.split('/')[-1]

if '?' in file_name:

file_name = file_name.split('?')[0]

with open(f"wallpaper/{file_name}", "wb") as f:

f.write(img_data)

```

- 使用 .content 获取二进制图片数据,并设置了10秒的超时时间防止卡死。

- 通过 / 分割URL提取文件名,并使用 split('?')[0] 剔除URL中可能携带的参数(如 1.jpg?v=123 变成 1.jpg),防止文件名格式错误。

- 以二进制写入模式"wb")将数据保存到本地。

7. 异常处理与防封控制

```python

except Exception as e:

print(f"下载失败: {src}, 原因: {e}")

time.sleep(0.5)

```

- try-except 捕获网络波动等异常,保证某一张图片下载失败不会导致整个程序崩溃。

- time.sleep(0.5) 是一种“礼貌爬取”策略,每下载一张图片暂停0.5秒,降低服务器压力,防止因请求过快被封禁IP。

---

### 三、 注意事项与改进建议

1. 法律与道德规范

- 爬取数据前,请务必查看目标网站的 robots.txt(如 https://weweclaw.com/robots.txt),尊重网站的爬虫协议。

- 不要过度频繁地请求,以免对目标服务器造成DDoS级别的压力。

2. 懒加载问题

- 当前代码只能下载**直接写在HTML源码中**的图片。如果目标网站使用了懒加载技术,图片的 src 可能被替换为 data-src,或者初始加载的是一个占位符。此时需要结合 Selenium 或 Playwright 等工具模拟滚动,或者分析网页的XHR/AJAX接口直接获取JSON数据。

3. 文件名冲突

- 当前逻辑直接使用URL末尾的名称作为文件名。如果不同目录下有同名图片(如 /a/1.jpg/b/1.jpg),后下载的会覆盖先下载的。建议使用哈希值或UUID重命名,或者将URL路径结构映射到本地目录。

4. 效率问题

- 代码使用的是同步串行下载(一张下完再下下一张),如果图片较多,速度较慢。可以考虑使用 concurrent.futures.ThreadPoolExecutor(线程池)或 asyncio(异步)来并发下载,大幅提升效率。

5. SSL证书验证

- 某些网站可能存在SSL证书问题导致 requests 报错,必要时可在 requests.get() 中添加 verify=False 参数(但不推荐在生产环境使用,有安全风险)。

如果你有进一步的需求(比如想改成多线程下载,或者想爬取动态加载的图片),随时可以告诉我,我会为你提供相应的代码!


评论