Python爬虫简单运用爬取代理IP的实现
前言这篇讲的是页面解析的技术面给定一个内容里含有ip:port的页面怎么把地址抽出来。这是一个很典型的「结构化抽取」练习和「去哪找代理」是两个问题。标题里说「爬取代理IP」很容易让人以为重点是「找到免费代理站然后抓下来」——本文不这么做也不会给出任何真实站点的地址示例里的 HTML 全部是我自己构造的本地字符串你在自己的编辑器里就能跑。有必要把来源问题说清楚因为它直接决定这篇要不要写。公开的「免费代理」来源不可信原因不是「质量差」这么简单你根本不知道流量经过谁。一个代理的运营者可以看到你通过它发出的全部明文请求包括你带的 Cookie、Token、以及请求内容这等于把一个陌生人插进了你的请求链路。有些「免费代理」本身就是蜜罐专门用来收集谁在用代理、以及通过代理访问了什么。有些地址根本不做转发而是把请求直接发出去再回来你的真实来源 IP 就这么泄露了。还有一类会在响应里注入内容做中间人式的篡改。所以即便你只是想练手也请把练习范围限定在自己构造的页面上真要用于生产来源必须是你有权使用的、可以追溯的自建代理、公司出口、付费代理服务。本机没有 Python 解释器也没有装requests等第三方库本文代码未在本机运行验证只作逐行人工推演用到的标准库html.parser、re、ipaddress都是随 Python 一起分发的第三方库的部分会注明需要先pip install。一、先定任务边界先说清楚这篇的输入输出项内容输入一段含有地址列表的 HTML 文本本文中为本地字符串输出一个去重后的host:port字符串列表不做的事不做真实网络请求、不访问任何真实站点、不校验地址是否可用前提页面来源是你有权解析的内容这里要特别强调「不做的事」本文只到「把文本里的地址抽出来」为止。抽出来的地址一律视为不可信能不能用、要不要用是另一个必须单独决策的问题。二、用标准库html.parser解析本地 HTML标准库自带一个 HTML 解析器html.parser它的用法是继承HTMLParser重写handle_starttag、handle_data、handle_endtag这几个钩子解析器在扫到对应结构时回调你。它不需要装任何东西这是它最大的优点。先构造一段页面。这是我自己写的演示 HTML表格里混了正常地址和几个不合法的值用来检验后面抽取逻辑的健壮性# 适用于 Python 3.8DEMO_HTML htmlbodytabletrthIP/thth端口/thth位置/th/trtrtd192.0.2.10/tdtd8080/tdtd演示机房 A/td/trtrtd192.0.2.11/tdtd3128/tdtd演示机房 B/td/trtrtd198.51.100.7/tdtd8888/tdtd演示机房 C/td/trtrtd999.1.1.1/tdtd80/tdtd非法 IP应被丢弃/td/trtrtd203.0.113.9/tdtd70000/tdtd端口越界应被丢弃/td/tr/table/body/html192.0.2.0/24、198.51.100.0/24、203.0.113.0/24是 RFC 5737 专门保留给文档示例的网段不会指向真实主机——这正是你写示例时该用的地址段。接下来写解析器把表格的每一行读出来# 适用于 Python 3.8from html.parser import HTMLParserclass TableRows(HTMLParser):把表格解析成 [[单元格, 单元格, ...], ...]def __init__(self):super().__init__()self.rows []self._row Noneself._cell Nonedef handle_starttag(self, tag, attrs):if tag tr:self._row []elif tag in (td, th) and self._row is not None:self._cell []def handle_data(self, data):if self._cell is not None:self._cell.append(data)def handle_endtag(self, tag):if tag in (td, th) and self._cell is not None:if self._row is not None:self._row.append(.join(self._cell).strip())self._cell Noneelif tag tr and self._row is not None:self.rows.append(self._row)self._row Noneparser TableRows()parser.feed(DEMO_HTML) # 解析本地字符串没有任何网络请求parser.close()for row in parser.rows:print(row)这里有几个容易踩的点都在代码里处理了td出现在tr之外时self._row是None所以每次用到它都先判空handle_data可能被调用多次单元格里嵌了别的标签时文字会被拆成几段回调所以单元格内容要先收集到一个列表再join不能直接赋值覆盖strip()必须在join之后做否则拿到的可能是带换行的碎片。feed()只负责喂数据建议最后调用一次close()让解析器把缓冲里的内容处理完。三、用ipaddress校验而不是只靠正则表格只是搬运工真正的校验在抽取这一步。最直观的做法是用正则匹配ip:port# 适用于 Python 3.8import ipaddressimport reADDR_RE re.compile(r(\d{1,3}(?:\.\d{1,3}){3}):(\d{1,5}))def to_endpoint(host, port_text):校验并规范化一个 host:port非法则返回 Nonetry:ipaddress.IPv4Address(host) # 非法 IPv4 会抛 AddressValueErrorexcept ipaddress.AddressValueError:return Nonetry:port int(port_text)except ValueError:return Noneif not (1 port 65535):return Nonereturn f{host}:{port}要理解正则和校验的分工正则只负责「找出长得像的片段」ipaddress才负责判断「它是不是合法的 IPv4」。上面那个\d{1,3}允许999.1.1.1正则完全无法识别而ipaddress.IPv4Address(999.1.1.1)会直接抛AddressValueError把它挡掉。端口同理——70000能通过正则的\d{1,5}但超出1..65535的范围必须自己检查。把两段接起来从解析出的表格行里抽地址# 适用于 Python 3.8# ADDR_RE 与 to_endpoint 沿用上一段代码里的定义def extract_endpoints(rows):seen set()result []for row in rows:if len(row) 2:continue# 演示页面把 IP 和端口放在两列里先用冒号拼回 ip:port 再匹配joined :.join(row[:2])m ADDR_RE.fullmatch(joined)if not m:continueendpoint to_endpoint(m.group(1), m.group(2))if endpoint and endpoint not in seen:seen.add(endpoint)result.append(endpoint)return resultprint(extract_endpoints(parser.rows))# 预期只保留 3 条合法地址非法 IP 与越界端口各被丢一条这里用的是fullmatch而不是search因为joined已经被我们拼成了恰好两段用fullmatch要求整串都符合ip:port的形状能挡掉「IP 列里混了别的东西」的情况。如果页面里是「一格里写着1.2.3.4:8080」这种形态直接用search找子串更合适——用哪个取决于文本的形状。用set去重是必要的同一批来源里重复地址很常见不去重会让下游的校验做无用功。四、第三方解析器思路与注意事项如果你的页面结构比表格复杂嵌套层很深、有大量属性、需要按 CSS 选择器或 XPath 定位标准库的html.parser会写得很啰嗦这时通常会用lxml或BeautifulSoupbs4。它们是第三方库需要先pip install lxml/pip install beautifulsoup4本机没有安装。用它们的思路是一模一样的只是把「手写状态机」换成「选择器」定位到承载地址的那批节点取出文本再走上面同一套正则加ipaddress的校验。本机既没有这些库我也无法运行验证所以这里不写出具体到参数名的调用——find_all也好、xpath也好参数名和返回类型请以这两个库的官方文档为准不要照抄任何你没核对过的签名。还有个层次问题值得单独提醒requests也是第三方库pip install requests它负责把页面取回来。但本文的所有示例都刻意不做网络请求——把「取」和「解析」分开既方便测试解析函数可以喂本地字符串也避免让示例默认指向某个真实站点。另外如果你要解析的是 HTML 里嵌的ip:port列表还要注意不要用正则去解析整个 HTML 文档。HTML 不是正则语言一个跨标签的正则匹配很容易在复杂页面上失控回溯、误匹配、把注释里的内容也抓出来。正则只应该作用在已经由解析器取出的文本节点上这是上面流程里先解析、后正则的原因。五、抽出来之后一律当作不可信抽到地址不等于能用。至少要再走这几步且每一步都要意识到「这些地址可能本身就是陷阱」去重上面已经做了逐个校验另写一个真实探测环节探测目标必须是你自己控制、且允许被探测的服务加来源标记记录每个地址来自哪一批数据出问题时能追溯绝不把来源不明的地址用于携带 Cookie、Token 或任何身份凭据的请求——这等于把凭据交给一个陌生人。第 4 条最要紧。用免费代理去访问需要登录的站点等于把你自己的会话凭据直接送给了代理运营者。常见坑点❌ 直接对一整篇 HTML 用正则匹配ip:port跳过解析器。✅ 先用html.parser之类的解析器取出文本节点再对文本节点用正则HTML 不是正则语言。❌ 只用正则\d{1,3}(\.\d{1,3}){3}判断地址合法性于是999.1.1.1被当成有效地址。✅ 正则找候选ipaddress.IPv4Address做合法性校验端口再单独检查1..65535。❌ 在handle_data里直接self._cell data结果一段文字被拆成多次回调时只剩最后一片。✅ 先把片段收集进列表handle_endtag时再join并strip。❌ 把td标签写在tr外面代码里self._row还是None就直接append抛AttributeError。✅ 每次使用前判空self._row is not None才写入。❌ 从公开免费代理站抓地址直接拿来用还带着自己的登录 Cookie。✅ 公开免费代理可能是蜜罐或中间人绝不用来源不明的代理发送任何凭据来源必须可追溯。❌ 相信「地址在页面上出现过就是可用的」不做去重也不做校验。✅ 去重、记录来源、独立校验三步都要做抽出来只是候选不是可用资源。❌ 为了解析复杂页面凭印象写一个bs4或lxml的调用参数名都没核对。✅ 这些是第三方库需先安装接口以各自官方文档为准不确定就不要写出具体参数名。❌ 在示例里写死一个真实站点地址读者一运行就去打了别人的服务器。✅ 示例一律用具名保留网段如192.0.2.0/24和本地构造的 HTML 字符串。总结步骤用什么关键点准备输入自己构造的本地 HTML 字符串用 RFC 5737 保留网段不指向真实站点解析结构html.parser.HTMLParser处理tr/td嵌套、多次handle_data、上下文判空抽取候选re正则只对文本节点匹配不在整篇文档上跑校验ipaddress.IPv4Address 端口范围正则管「像」ipaddress管「是不是合法」收尾set去重、来源标记抽出来的地址一律视为不可信「爬取代理IP」这件事技术上的难点其实很有限——解析一段结构化的 HTML、抽字段、做校验都是基础操作。真正需要投入判断力的是来源和用途这段 HTML 从哪来、抽出的地址能不能信、拿它们去干什么。示例用本地字符串不只是因为本机没有网络环境更是因为在教学场景里让读者把注意力放在解析逻辑而不是「哪个站还能抓」上才是对的。参考html.parser、re、ipaddress的接口以 Python 官方文档为准lxml、BeautifulSoup、requests为第三方库需另行安装接口以其官方文档为准本文代码未在本机运行仅作人工推演。

相关新闻

PCA9422+PIC24双芯片电源管理设计实战

PCA9422+PIC24双芯片电源管理设计实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/10 13:39:40 阅读更多 →
H5免费制作:邀请函小程序哪个好用?我把 5 个常见小程序挨个用了一遍

H5免费制作:邀请函小程序哪个好用?我把 5 个常见小程序挨个用了一遍

结论先行:邀请函小程序哪个好,没有一个能 cover 全部场景的标准答案。这两年帮朋友家人做了不少电子邀请函,前阵子又被问到"还有别的工具吗",干脆花了几天把常见的几个小程序挨个注册试了一遍,得出一个相对清晰的结论——「邀请函小…

2026/10/10 13:39:39 阅读更多 →
Python微服务量化交易系统:gRPC+Redis本地实盘级架构

Python微服务量化交易系统:gRPC+Redis本地实盘级架构

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/10 13:39:39 阅读更多 →

最新新闻

【Claude Code】BMad-Method 多智能体协作实战:PRD 与架构文档一键生成,TaoToken 统一 Key 接入

【Claude Code】BMad-Method 多智能体协作实战:PRD 与架构文档一键生成,TaoToken 统一 Key 接入

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/10 21:46:35 阅读更多 →
JVM target 5编译报错排查:JDK 17下Language level与Maven配置修复指南

JVM target 5编译报错排查:JDK 17下Language level与Maven配置修复指南

1. 这个报错到底在说什么——先把错误文本拆开看先放出完整报错原文,很多朋友发的截图往往只截了前半截,导致搜不到有用的解决方案:java: Cannot compile module api-test-fix1 configured for JVM target 5: the JDK Oracle OpenJDK 17.0 do…

2026/10/10 21:46:35 阅读更多 →
标签即输入:拆解 GLiNER2.5-Decide 的 Schema 驱动分类,为什么它不需要固定输出层

标签即输入:拆解 GLiNER2.5-Decide 的 Schema 驱动分类,为什么它不需要固定输出层

标签即输入:拆解 GLiNER2.5-Decide 的 Schema 驱动分类,为什么它不需要固定输出层 【免费下载链接】GLiNER2.5-Decide 项目地址: https://ai.gitcode.com/hf_mirrors/fastino/GLiNER2.5-Decide 传统文本分类模型的命运,从诞生那一刻起…

2026/10/10 21:46:35 阅读更多 →
Windows 开机自启的 OpenClaw 重启失败?Telegram 报错?三步定位 + 五步复现(含完整命令)

Windows 开机自启的 OpenClaw 重启失败?Telegram 报错?三步定位 + 五步复现(含完整命令)

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/10 21:46:35 阅读更多 →
Kimsuky 2026 离线 AI 攻击栈拆解:从 GitPower 到 RAG 的间谍活动演化与 TaoToken 统一通道验证

Kimsuky 2026 离线 AI 攻击栈拆解:从 GitPower 到 RAG 的间谍活动演化与 TaoToken 统一通道验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/10 21:46:35 阅读更多 →
GPU算力怎么选?从并行计算到AI大模型实战指南

GPU算力怎么选?从并行计算到AI大模型实战指南

今年明显感觉身边聊GPU算力的人变多了。以前大家问显卡,翻来覆去就是“能不能流畅玩XX游戏”“帧率多少”,现在画风完全不一样了,开口就是“这卡能跑多少B参数的模型”“显存够不够微调”“深度学习吃不吃得消”。说白了,不管游戏…

2026/10/10 21:45:34 阅读更多 →

日新闻

卫星轨道分类全解析:从LEO到GEO的选型逻辑与工程实践

卫星轨道分类全解析:从LEO到GEO的选型逻辑与工程实践

1. 从“卫星轨道分类”这个标题说起:为什么值得花时间搞懂第一次接触“卫星轨道分类”这个概念,很多人会觉得它离自己很远——不就是天上的星星怎么转吗?但如果你正在做航天任务规划、遥感数据接收、星座设计,甚至只是准备一场航天…

2026/10/10 0:00:39 阅读更多 →
Spring AOP 核心原理与实战:从概念到日志切面落地

Spring AOP 核心原理与实战:从概念到日志切面落地

1. 从一个真实痛点说起:为什么你的代码里到处都是重复逻辑刚入行那会儿,我写过一个用户管理模块,注册、登录、改密码、注销四个接口。每个接口里都塞了几乎一样的日志打印、参数校验、事务开启和提交。当时觉得没什么,能跑就行。直…

2026/10/10 0:00:40 阅读更多 →
Python招聘数据采集与分析可视化:从采集清洗到薪资技能城市可视化全链路

Python招聘数据采集与分析可视化:从采集清洗到薪资技能城市可视化全链路

简介:这是一套面向计算机相关专业学生与项目实战学习者的Python数据采集与分析可视化完整项目,以Boss直聘岗位数据为对象,适合用作毕业设计、课程设计或期末大作业。资源包共38个文件,约246KB,以13个py源码文件为核心&…

2026/10/10 0:00:40 阅读更多 →

周新闻

KT148A语音芯片外挂8002D功放的工程实践指南

KT148A语音芯片外挂8002D功放的工程实践指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/10 11:14:25 阅读更多 →
LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/10 1:36:08 阅读更多 →
ARM架构深度解析:从RISC设计理念到交叉编译实战

ARM架构深度解析:从RISC设计理念到交叉编译实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/10 11:14:58 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/10 5:23:50 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/9 21:32:20 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/10 10:38:42 阅读更多 →