Python 2.7.5爬取网页后正则匹配IP无结果,求正确实现方式
问题分析与解决方案
嘿,我来帮你梳理下问题所在,以及更靠谱的解决办法:
原代码的核心问题
你当前的代码是逐行读取网页内容并逐行匹配正则,但这里有两个关键问题:
- 网页的HTML结构里,IP/子网段并不是以“单独一行”的形式存在的,它们嵌套在
<td>标签中,和其他HTML代码混在一起,逐行搜索自然匹配不到。 - Python 2.7中
urllib2.urlopen返回的是字节流,直接处理可能存在编码问题,也会影响正则的匹配结果。
另外,你对BeautifulSoup的理解有偏差——它恰恰是处理这种表格结构的绝佳工具,比正则表达式更稳定、更易维护。
方案1:改进正则匹配方式(快速调整)
如果坚持用正则,你需要先读取整个网页内容,处理编码后再批量搜索所有匹配项,而不是逐行处理:
import urllib2 import re # 获取完整网页内容并转成Unicode(解决编码问题) response = urllib2.urlopen("https://ipinfo.io/AS32244") content = response.read().decode('utf-8') # 编译正则表达式 ip_regex = re.compile(r"(?:\d{1,3}\.){3}\d{1,3}(?:/\d{1,2})?") # 查找所有匹配的IP/子网段 ip_list = ip_regex.findall(content) # 输出结果 for ip in ip_list: print(ip)
方案2:用BeautifulSoup解析表格(更推荐)
因为目标IP/子网段都在网页的表格里,用BeautifulSoup定位表格和对应列,能精准提取内容,还不会匹配到页面中其他无关的IP(比如页面底部的统计IP)。
首先需要安装BeautifulSoup4(Python 2.7版本可以用pip install beautifulsoup4安装),然后代码如下:
import urllib2 from bs4 import BeautifulSoup # 获取网页内容并处理编码 response = urllib2.urlopen("https://ipinfo.io/AS32244") content = response.read().decode('utf-8') # 初始化BeautifulSoup解析器 soup = BeautifulSoup(content, 'html.parser') # 找到页面中的目标表格(页面第一个表格就是AS信息表) target_table = soup.find('table') # 遍历表格行,跳过表头(第一行) for row in target_table.find_all('tr')[1:]: # 提取每行第一列的内容(就是IP/子网段) ip_segment = row.find_all('td')[0].get_text(strip=True) print(ip_segment)
为什么推荐BeautifulSoup?
正则表达式适合处理纯文本,但HTML是结构化内容,用解析器提取的优势很明显:
- 不会误匹配页面中其他无关的IP地址;
- 如果网页结构有小幅度调整(比如标签样式变化),调整选择器比修改正则简单得多;
- 代码可读性更强,后续维护成本更低。
内容的提问来源于stack exchange,提问作者Jason




