当前位置: 首页 > article >正文

Python爬虫实战:用urllib和正则搞定E-Hentai图片批量下载(附完整代码与避坑指南)

Python高效爬虫实战多线程下载与智能错误处理引言在当今数据驱动的时代网络爬虫已成为获取互联网信息的重要工具。对于开发者而言掌握高效的爬虫技术不仅能提升工作效率还能解决许多实际业务场景中的数据采集需求。本文将深入探讨如何利用Python标准库构建一个健壮的图片爬虫系统重点解决网络不稳定环境下的下载难题。与常见的简单爬虫教程不同我们将从工程化角度出发设计一个具备自动重试机制、多线程加速和智能错误处理的完整解决方案。无论您是需要批量下载图片素材的设计师还是进行数据收集的研究人员这套方法都能显著提升您的工作效率。1. 核心工具选择与环境准备在Python生态中虽然Requests和Scrapy等第三方库功能强大但标准库urllib在某些受限环境下如无法安装第三方包的场景展现出独特优势。配合re模块的正则表达式处理能力可以构建不依赖外部库的轻量级爬虫。1.1 基础环境配置确保您的Python环境为3.6版本这是为了使用更现代的字符串格式化方式和类型提示功能。检查Python版本python --version1.2 必要模块导入我们的爬虫将主要依赖以下标准库模块import urllib.request import urllib.error import re import os import time from concurrent.futures import ThreadPoolExecutor, as_completed from functools import partial2. 网页解析与链接提取策略2.1 智能请求头设置现代网站普遍对爬虫有基础防护合理的请求头设置能显著降低被拦截概率DEFAULT_HEADERS { User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36, Accept: text/html,application/xhtmlxml,application/xml;q0.9,image/webp,*/*;q0.8, Accept-Language: en-US,en;q0.5, Connection: keep-alive, Upgrade-Insecure-Requests: 1 }2.2 稳健的页面获取函数考虑到网络波动我们需要实现带重试机制的页面获取功能def fetch_page(url, max_retries3, timeout15): retry_delay 2 # 初始重试延迟秒数 for attempt in range(max_retries): try: req urllib.request.Request(url, headersDEFAULT_HEADERS) with urllib.request.urlopen(req, timeouttimeout) as response: return response.read().decode(utf-8) except urllib.error.URLError as e: print(fAttempt {attempt 1} failed: {str(e)}) if attempt max_retries - 1: time.sleep(retry_delay * (attempt 1)) return None2.3 精准的图片链接提取使用正则表达式提取图片链接时应考虑多种可能的HTML结构def extract_image_links(html_content): # 匹配多种常见的图片标签模式 patterns [ rimg[^]src([^]\.(?:jpg|png|jpeg|gif|webp)), rbackground-image:\s*url\([\]?([^\)]\.(?:jpg|png|jpeg|gif|webp)), rdata-src[\]([^\]\.(?:jpg|png|jpeg|gif|webp))[\] ] unique_links set() for pattern in patterns: matches re.findall(pattern, html_content, re.IGNORECASE) unique_links.update(matches) return list(unique_links)3. 高级下载功能实现3.1 带自动重试的下载器def download_image(url, save_path, max_retries3): filename os.path.basename(url) full_path os.path.join(save_path, filename) for attempt in range(max_retries): try: req urllib.request.Request(url, headersDEFAULT_HEADERS) with urllib.request.urlopen(req, timeout30) as response: with open(full_path, wb) as f: f.write(response.read()) return True except Exception as e: print(fDownload attempt {attempt 1} failed for {url}: {str(e)}) if attempt max_retries - 1: time.sleep((attempt 1) * 2) return False3.2 多线程下载控制器def batch_download(image_urls, save_dir, max_workers5): if not os.path.exists(save_dir): os.makedirs(save_dir) download_func partial(download_image, save_pathsave_dir) with ThreadPoolExecutor(max_workersmax_workers) as executor: futures {executor.submit(download_func, url): url for url in image_urls} results [] for future in as_completed(futures): url futures[future] try: results.append((url, future.result())) except Exception as e: results.append((url, False)) print(fError downloading {url}: {str(e)}) return results4. 工程化增强与异常处理4.1 完善的日志系统import logging def setup_logger(name, log_file, levellogging.INFO): formatter logging.Formatter(%(asctime)s %(levelname)s %(message)s) handler logging.FileHandler(log_file) handler.setFormatter(formatter) logger logging.getLogger(name) logger.setLevel(level) logger.addHandler(handler) return logger # 使用示例 crawler_logger setup_logger(image_crawler, crawler.log)4.2 智能限速机制class DownloadLimiter: def __init__(self, max_per_minute): self.max_per_minute max_per_minute self.timestamps [] def wait_if_needed(self): now time.time() # 移除超过1分钟的时间戳 self.timestamps [t for t in self.timestamps if now - t 60] if len(self.timestamps) self.max_per_minute: sleep_time 60 - (now - self.timestamps[0]) time.sleep(max(0, sleep_time)) self.timestamps.append(time.time()) # 使用示例 limiter DownloadLimiter(60) # 每分钟最多60次请求5. 完整工作流整合5.1 主控制函数def crawl_website(base_url, output_dir, page_limit10): logger setup_logger(main_crawler, main_crawler.log) limiter DownloadLimiter(60) all_image_urls [] for page_num in range(page_limit): limiter.wait_if_needed() page_url f{base_url}?p{page_num} if page_num 0 else base_url logger.info(fProcessing page: {page_url}) html fetch_page(page_url) if not html: logger.warning(fFailed to fetch page {page_num}) continue image_urls extract_image_links(html) if not image_urls: logger.info(fNo images found on page {page_num}, stopping) break all_image_urls.extend(image_urls) if all_image_urls: logger.info(fFound {len(all_image_urls)} images total) results batch_download(all_image_urls, output_dir) success_count sum(1 for _, success in results if success) logger.info(fDownloaded {success_count}/{len(all_image_urls)} successfully) else: logger.warning(No images found on any page)5.2 实际调用示例if __name__ __main__: # 示例调用 - 替换为实际参数 target_url https://example.com/gallery save_directory ./downloaded_images crawl_website(target_url, save_directory)6. 性能优化技巧连接复用通过创建自定义的OpenerDirector来复用HTTP连接DNS缓存实现简单的DNS缓存减少查询时间智能分页动态检测最后一页而非固定页数限制增量爬取记录已下载文件避免重复下载带宽控制根据网络状况动态调整并发数# 连接复用示例 opener urllib.request.build_opener() urllib.request.install_opener(opener) # DNS缓存示例 import socket _dns_cache {} def cached_getaddrinfo(*args, **kwargs): if args in _dns_cache: return _dns_cache[args] result socket.getaddrinfo(*args, **kwargs) _dns_cache[args] result return result socket.getaddrinfo cached_getaddrinfo7. 常见问题解决方案7.1 403 Forbidden错误可能原因及解决方案User-Agent被识别定期轮换多个User-Agent字符串请求频率过高实现更严格的请求间隔控制Cookie验证模拟完整的浏览器行为包括Cookie处理7.2 图片下载不完整处理方法实现分块下载和校验添加文件完整性检查如检查文件头尾标志对部分下载的文件实现断点续传7.3 反爬虫机制规避防御策略随机化请求间隔模拟鼠标移动等人类行为模式使用住宅代理IP轮换8. 扩展功能建议自动分类系统根据图片内容或元数据自动分类存储去重机制基于MD5或感知哈希的重复图片检测质量过滤自动过滤低分辨率或低质量图片元数据提取保存图片的EXIF等信息到数据库进度可视化实时显示下载进度和速度# 简单的MD5去重示例 import hashlib def get_file_md5(filepath): with open(filepath, rb) as f: return hashlib.md5(f.read()).hexdigest() # 在下载前检查是否已存在相同内容的文件9. 安全与合规注意事项robots.txt遵守始终检查目标网站的robots.txt文件版权意识仅下载明确允许下载的内容请求间隔设置合理的请求间隔避免对目标服务器造成负担数据存储妥善处理下载的数据遵守相关法律法规身份标识在User-Agent中包含联系信息以便网站管理员联系提示在实际项目中建议添加--user-agent参数允许用户自定义标识并在其中包含可联系的邮箱地址10. 进一步学习资源官方文档Python urllib文档HTTP协议RFC标准进阶工具Scrapy框架Selenium自动化测试工具相关技术正则表达式高级技巧网络协议分析性能优化异步IO编程(asyncio)分布式爬虫设计在实际项目中这套系统经过适当调整后成功实现了每天稳定下载数十万张图片的可靠性。关键点在于完善的错误处理机制和合理的性能平衡既不过度消耗目标网站资源又能最大化利用本地带宽。

相关文章:

Python爬虫实战:用urllib和正则搞定E-Hentai图片批量下载(附完整代码与避坑指南)

Python高效爬虫实战:多线程下载与智能错误处理 引言 在当今数据驱动的时代,网络爬虫已成为获取互联网信息的重要工具。对于开发者而言,掌握高效的爬虫技术不仅能提升工作效率,还能解决许多实际业务场景中的数据采集需求。本文将深…...

016、气压计原理与高度测量

飞控算法从入门到精通 016 气压计原理与高度测量 一、一次炸机带来的教训 去年夏天,我在一个四轴飞行器上调试定高悬停。气压计用的是MS5611,数据手册翻烂了,滤波算法也上了,地面站里高度曲线看着挺平滑。结果一上天,飞机像喝醉了酒——先是莫名其妙往下掉半米,然后猛…...

MTKClient实战指南:联发科设备刷机与逆向工程全面解决方案

MTKClient实战指南:联发科设备刷机与逆向工程全面解决方案 【免费下载链接】mtkclient MTK reverse engineering and flash tool 项目地址: https://gitcode.com/gh_mirrors/mt/mtkclient MTKClient是一款专为联发科芯片设备设计的开源逆向工程与刷机工具&am…...

在Linux Mint上搞定Synopsys VCS和Verdi 2018.06:一个学生党的完整踩坑与配置实录

在Linux Mint上搞定Synopsys VCS和Verdi 2018.06:一个学生党的完整踩坑与配置实录 作为一名微电子专业的学生,第一次接触Synopsys的VCS和Verdi工具时,我完全被它们的强大功能所震撼。然而,当我在自己的Linux Mint系统上尝试安装这…...

可观测性技术栈选型指南:从Prometheus到OpenTelemetry的实践路径

1. 项目概述:一个可观测性技术栈的“藏宝图”如果你正在构建或维护一个现代化的、需要高可靠性的软件系统,那么“可观测性”这个词对你来说一定不陌生。它早已超越了传统的监控,成为确保系统健康、快速定位问题的核心能力。然而,当…...

保姆级避坑指南:用GGCNN源码处理Cornell抓取数据集,解决tiff文件生成失败问题

GGCNN源码实战:Cornell数据集预处理深度排错指南 第一次运行GGCNN的Cornell数据集预处理脚本时,我盯着毫无反应的终端窗口足足等了十分钟——没有进度条,没有错误提示,只有光标在无情地闪烁。这大概是每个复现论文的开发者都会经历…...

自然语言脚本编程:用humanscript实现意图驱动的自动化

1. 项目概述:当代码遇上自然语言最近在折腾一些自动化脚本时,我总在想,有没有一种方式,能让写脚本这件事变得像写待办事项清单一样简单?比如,我想让电脑“把今天下载的图片都压缩一下,然后传到网…...

基于Next.js 15与React 19构建现代化个人作品集:技术选型与工程实践

1. 项目概述:为什么选择 Next.js 15 构建现代个人作品集 作为一名在前后端领域摸爬滚打了十多年的开发者,我见过也亲手搭建过无数种个人作品集网站。从早期的纯静态 HTML/CSS,到 jQuery 时代,再到 React/Vue 等框架的兴起&#x…...

模型运行记录

1753...

Fomu FPGA工作坊:从LED闪烁到RISC-V软核的微型硬件开发指南

1. 项目概述:当FPGA遇见指尖,一场硬件的微型革命如果你对嵌入式开发、硬件编程感兴趣,但又觉得传统的FPGA开发板笨重、昂贵且入门门槛高,那么im-tomu/fomu-workshop这个项目可能会让你眼前一亮。这不仅仅是一个代码仓库&#xff0…...

量子信号处理技术及其在离子阱系统中的应用

1. 量子信号处理技术概述量子信号处理(Quantum Signal Processing, QSP)是近年来量子计算领域涌现的一项基础性技术,它通过精心设计的量子比特旋转序列,实现对量子数据的系统性多项式变换。这项技术的核心价值在于,它为…...

数据中台下半场比的是治理:六家主流厂商四维度横向测评

一、数据治理:决定数据中台价值兑现的关键变量2026年,一个行业的共识正在变得清晰:数据中台的上限由计算架构决定,但下限由数据治理决定。过去数年,大量企业投入资源搭建了数据中台的基础设施——数据湖、数仓、调度引…...

FreeVA:零训练成本,用图像大模型实现视频理解的新范式

1. 项目概述:一个无需训练的“零成本”视频助手 最近在折腾多模态大模型(MLLM)的时候,我发现了一个挺有意思的现象:大家一提到让模型理解视频,第一反应就是得搞“视频指令微调”。简单说,就是拿…...

权限割裂、数据延迟、协同断点——Gemini Workspace整合失败的90%源于这4个配置盲区

更多请点击: https://intelliparadigm.com 第一章:权限割裂、数据延迟、协同断点——Gemini Workspace整合失败的90%源于这4个配置盲区 在企业级部署 Gemini Workspace 时,大量团队遭遇“功能可登录但协作不可用”的隐性故障。根本原因并非 …...

语言启蒙到底要不要背单词

语言启蒙阶段到底要不要背单词?我更愿意把这个问题换一种问法:这些词是不是能和声音、图像、语境连起来,并且隔几天还能回来一次。 如果只是拿一张词表硬记,入门用户很容易觉得枯燥。可如果完全不接触词汇,后面的听读…...

【AI】短期记忆:会话上下文管理与实现

短期记忆:会话上下文管理与实现 📝 本章学习目标:本章深入探讨记忆机制,这是AI Agent持续执行的关键能力。通过本章学习,你将全面掌握"短期记忆:会话上下文管理与实现"这一核心主题。 一、引言&a…...

droidrun-agent:基于MCP协议连接AI智能体与安卓设备的自动化桥梁

1. 项目概述:当AI助手需要“动手”时在AI Agent(智能体)领域,我们常常遇到一个瓶颈:模型可以生成完美的计划、写出漂亮的代码,但它如何与真实世界交互,尤其是如何操作一台物理设备?比…...

NSA 5G:从双连接到网络切片,解析5G组网演进之路

1. 非独立组网5G:一场关于“先有鸡还是先有蛋”的行业博弈如果你在2017年的世界移动通信大会(MWC)现场,可能会感到一丝困惑。前一年,整个行业还在为5G描绘一幅彻底颠覆4G、开启万物互联新纪元的宏伟蓝图。然而一年后&a…...

数字信号处理中的统计与概率基础解析

1. 数字信号处理中的统计与概率基础 在数字信号处理(DSP)领域,统计和概率理论构成了分析和处理信号的核心数学工具。信号在采集、传输和处理过程中不可避免地会受到各种干扰和噪声的影响,这些干扰可能来自测量系统本身&#xff0c…...

高速SerDes设计中BER预测的智能应力输入方法

1. 高速串行链路设计中的BER预测挑战在当今高速数字系统设计中,SerDes(串行器/解串器)技术已成为主流接口方案,数据传输速率已突破10Gbps大关。随着速率提升,信号完整性(SI)问题日益突出,其中误码率(BER)预…...

十年后,编程还会是人类的工作吗?

一个正在被重写的职业剧本站在2026年的中点眺望2036年,没有人能准确预言未来。但作为软件测试从业者,我们或许是离“编程工作是否会被取代”这个答案最近的一群人。因为我们每天的工作,就是审视代码的边界、挖掘逻辑的漏洞、评估系统的风险。…...

使用Taotoken管理控制台进行APIKey的权限划分与审计日志查看

🚀 告别海外账号与网络限制!稳定直连全球优质大模型,限时半价接入中。 👉 点击领取海量免费额度 使用Taotoken管理控制台进行APIKey的权限划分与审计日志查看 在团队协作开发或构建多应用服务时,统一管理大模型API的访…...

Rails控制台集成AI助手:ask_chatgpt Gem的实践指南

1. 项目概述:在Rails控制台里装一个AI助手 如果你是一个Ruby on Rails开发者,并且每天都在跟Rails控制台( rails console )打交道,那你肯定有过这样的时刻:盯着一段复杂的ActiveRecord查询,或…...

知识付费浪潮下的技术学习:是捷径,还是新的信息茧房?

当“知识”成为一种商品打开手机,各类技术公众号、知识星球、极客时间专栏、慕课网实战课、B站充电视频……铺天盖地的“测试开发进阶”“性能测试大师班”“自动化测试框架实战”正以9.9元、199元、3999元的价格被明码标价。作为一名软件测试工程师,我们…...

VSCode调试C++项目全攻略:从CMake工程配置到Native Debug实战(含传参技巧)

VSCode调试C项目全攻略:从CMake工程配置到Native Debug实战(含传参技巧) 在当今的C开发环境中,高效调试已成为提升生产力的关键环节。对于使用CMake管理的中大型项目,如何在VSCode中实现无缝调试体验,是许多…...

Avalonia AI助手插件:为.NET跨平台UI开发注入专家级智能

1. 项目概述:一个为Avalonia开发者量身定制的AI助手插件如果你正在使用Avalonia这个跨平台的.NET UI框架,并且同时也在探索如何利用像Claude、ChatGPT、GitHub Copilot这样的AI助手来提升开发效率,那么你很可能遇到过这样的困境:当…...

告别手动传包!用Pypiserver在内网搭建Python私有源,团队协作效率翻倍

告别手动传包!用Pypiserver在内网搭建Python私有源,团队协作效率翻倍 在团队开发中,Python依赖管理常常成为效率瓶颈。想象这样的场景:新同事加入项目,需要配置开发环境,却因为内网限制无法直接访问PyPI&a…...

黑客马拉松(Hackathon)文化:是创新工场,还是疲劳表演?

在软件工程的世界里,我们测试人常常站在产品交付的最后一道防线上,习惯了在严谨的流程、详尽的用例和稳定的环境中寻找缺陷。而黑客马拉松,这个充满激情、混乱与极限编程的代名词,对我们来说,既像是一个遥不可及的极客…...

Steam成就管理神器:如何在5分钟内解锁所有成就的终极完整指南

Steam成就管理神器:如何在5分钟内解锁所有成就的终极完整指南 【免费下载链接】SteamAchievementManager A manager for game achievements in Steam. 项目地址: https://gitcode.com/gh_mirrors/st/SteamAchievementManager 还在为Steam游戏中那些遥不可及的…...

记一次ubuntu 22.04安装旧版 MongoDB 4.2

22.04版本比较新,由于mongodb 2.4太老了,安装会遇到问题。特此记录1. 下载mongodb包wget https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-ubuntu1804-4.2.24.tgz2. 解压到当前目录sudo tar -zxvf mongodb-linux-x86_64-ubuntu1804-4.2.24.tgz3.…...