Python编写网页图片批量下载脚本与反爬应对

慢慢来
慢慢来
发布时间:2026-10-12| 3人浏览过
原创

本文介绍如何使用Python编写网页图片批量抓取脚本。通过定位页码信息、利用正则表达式解析HTML获取目标链接,结合设置代理服务器与自定义请求头绕过基础拦截,最终将图片按原文件名保存至本地。文中附带完整请求封装代码及IP阻断、超时等常见问题的排错方案。

Python实现图片批量抓取的执行逻辑与准备

编写自动化抓取脚本通常遵循“获取列表信息 → 解析目标元素 → 发起下载请求 → 落地存储”的标准路径。以特定图文板块为例,程序需要先读取最新页码,向前遍历每一页的源代码,从中匹配出图片的真实访问链接,最后定向写入本地文件夹。由于多数平台具备基础的频率检测机制,直接裸跑请求极易触发服务端拦截,因此需在初始化阶段同步构建携带标准浏览器标识的HTTP客户端。

第1步:定位动态页码索引

页面导航区域通常会标注当前所处的分页节点。通过观察源码DOM结构,可利用正则表达式精准捕获该数值,作为后续循环下载的起始基准。提取成功后,即可根据页码倒序或顺序生成待抓取的目标URL。

页面分页导航区域的HTML结构示意
定位源码中的分页标记与数值容器

def __getNewPage(self):
    pageCode = self.Get(self.__Url)
    # 匹配当前评论/分页页码标识
    pattern = re.compile(r'<div .*?cp-pagenavi">.*?<span .*?current-comment-page">\[(.*?)\]</span>', re.S)
    newPage = re.search(pattern, pageCode)
    if newPage:
        return newPage.group(1)
    # 页码解析失败时的安全回退值
    return 1500

第2步:匹配单页全部资源链接

锁定有效页号后,拼接对应分页路径再次请求。在返回的文本流中,目标图片标签往往包裹在特定的父级容器内。编写非贪婪模式的匹配规则可高效提取完整路径,避免截断或引入干扰字符。

图片链接所在HTML段落结构示意
识别图片标签所属的DOM层级关系

def __getAllPicUrl(self, pageIndex):
    realurl = self.__Url + "page-" + str(pageIndex) + "#comments"
    pageCode = self.Get(realurl)
    # 提取包裹在段落内的图片源地址
    pattern = re.compile('<p>.*?<a .*?view_img_link">.*?</a>.*?<img src="(.*?)".*?</p>', re.S)
    items = re.findall(pattern, pageCode)
    self.__savePics(items, self.__floder)

第3步:构建带代理的请求容器

频繁发起同频道的GET请求会迅速消耗信誉配额,服务端可能直接切断连接。此时程序将无法继续拉取数据,控制台日志常表现为获取到空内容或异常状态。解决方案是接入外部代理节点,并在请求管道中注入标准的User-Agent与Cookie管理机制。同时适当放宽Socket超时阈值,防止网络波动导致的中途断开。

反爬拦截导致请求失败的响应特征
识别被屏蔽或拒绝连接的典型现象
代理连接速度与超时设置提示
合理配置超时参数保障下载连续性

底层通信类需兼顾Header伪装、gzip解压校验与错误降级处理。以下为适配现代运行环境的封装示例:


import urllib.request, http.cookiejar, socket, zlib, io

class HttpClient:
    def __init__(self):
        self.__cookie = http.cookiejar.CookieJar()
        # 按需替换为稳定可用的出口节点
        proxy_handler = urllib.request.ProxyHandler({"http": "http://42.121.6.80:8080"})
        opener = urllib.request.build_opener(
            urllib.request.HTTPCookieProcessor(self.__cookie), 
            proxy_handler
        )
        opener.addheaders = [
            ('Accept', 'application/javascript, */*;q=0.8'),
            ('User-Agent', 'Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0)')
        ]
        urllib.request.install_opener(opener)

    def Get(self, url, refer=None):
        try:
            req = urllib.request.Request(url)
            if refer:
                req.add_header('Referer', refer)
            response = urllib.request.urlopen(req, timeout=120)
            html = response.read()
            gzipped = response.headers.get('Content-Encoding')
            if gzipped == 'gzip':
                html = zlib.decompress(html, 16+zlib.MAX_WBITS)
            return html.decode('utf-8', errors='ignore')
        except urllib.error.HTTPError as e:
            return e.read().decode('utf-8', errors='ignore')
        except (socket.timeout, socket.error):
            return ''

    def Download(self, url, filepath):
        urllib.request.urlretrieve(url, filepath)

第4步:统筹调度与文件落盘

将网络获取的二进制流按原始后缀命名写入新建的缓存目录。若目录已存在则切换工作路径继续追加,未找到新页码标记时启用安全回退值终止循环。完整的主控类需继承上述通信层,串联页码推算、链接过滤与磁盘写入动作。


import sys, os

class JianDan(HttpClient):
    def __init__(self):
        self.__pageIndex = 1500 
        self.__Url = "http://jandan.net/ooxx/"
        self.__floder = "jiandan"

    def __savePics(self, img_addr, folder):
        for item in img_addr:
            filename = item.split('/')[-1]
            print("正在保存图片:" + filename)
            self.Download(item, filename)

    def start(self):
        if not os.path.exists(self.__floder):
            os.mkdir(self.__floder)
        os.chdir(self.__floder)
        
        page = int(self.__getNewPage())
        # 按页码区间遍历抓取
        for i in range(self.__pageIndex, page):
            self.__getAllPicUrl(i)

if __name__ == '__main__':
    jd = JianDan()
    jd.start()

运行验证与常见排错指引

程序跑通后,可通过检查目标文件夹内的文件大小与数量确认抓取结果。若遇到以下状况,可按对应方向排查:

  • 请求被拒或持续返回空字节:当前代理节点失效或处于高负载状态。更换优质IP段,并将 timeout 参数调至 150 以上。
  • 编码报错(UnicodeDecodeError):部分站点未统一声明字符集。可在解码前强制指定 utf-8 或使用 errors='ignore' 跳过非法字节。
  • IO阻塞或进度停滞:批量写入大体积图像时建议在循环内加入延时器(如 time.sleep(1)),降低对源站压力的同时提升自身队列稳定性。

总结

以上就是使用Python进行网页图片批量抓取脚本编写的详细内容,更多关于Python网络爬虫开发与反爬应对技巧的资料请关注本站其它相关文章!

相关标签:

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。