如何从HTML字符串中提取IP地址?

29

我想使用 Python 从一个字符串(实际上是一行 HTML)中提取 IP 地址。

>>> s = "<html><head><title>Current IP Check</title></head><body>Current IP Address: 165.91.15.131</body></html>"

-- '165.91.15.131' 是我想要的!

我尝试使用正则表达式,但目前只能获取到第一个数字。

>>> import re
>>> ip = re.findall( r'([0-9]+)(?:\.[0-9]+){3}', s )
>>> ip
['165']

但我对正则表达式并不是很熟练;上面的代码是从网上找到并进行了修改。


可能是重复的问题:正则表达式匹配主机名或IP地址? - Denis Otkidach
6个回答

75

移除你的捕获组:

ip = re.findall( r'[0-9]+(?:\.[0-9]+){3}', s )

结果:

['165.91.15.131']

注意:

  • 如果你在解析HTML,可能最好使用BeautifulSoup库。
  • 你的正则表达式匹配了一些无效的IP地址,例如0.00.999.9999。这不一定是个问题,但你应该意识到这一点,并且可能需要处理这种情况。你可以将+改为{1,3}以部分修复此问题,而不使正则表达式过于复杂。

2
你可以使用正则表达式来接受有效的IP地址 "\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b" - rcbevans
非常好。对于那些对(?:...)的影响感兴趣的人,可以在文档http://docs.python.org/2/library/re.html中找到它:“(?:...)正则括号的非捕获版本。匹配括号内的任何正则表达式,但是组匹配的子字符串不能在执行匹配后检索或稍后在模式中引用。” - RussellStewart
@o0rebelious0o 令人印象深刻的正则表达式。为了方便起见,在您已经使用这个python解决方案的情况下,您可以使用ipaddress.ip_address(ip)来检查它。 - m3nda

6
您可以使用以下正则表达式来捕获有效的IP地址。
re.findall(r'\b25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?\.25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?\.25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?\.25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?\b',s)

返回值

['165', '91', '15', '131']

2
从技术上讲,这并不匹配有效的IP地址,而是有效的八位组。它们可以有任意数量,可能需要在单独的步骤中进行检查。 - Jakob Borg

4
import re

ipPattern = re.compile('\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}')

findIP = re.findall(ipPattern,s)

findIP contains ['165.91.15.131']

4
您可以使用以下正则表达式提取有效的IP地址,避免以下错误:
1. 一些将 123.456.789.111 判断为有效IP地址
2. 一些不将 127.0.00.1 判断为有效IP地址
3. 一些不将以零开头的IP地址,如 08.8.8.8 判断为有效IP地址。

因此,我在这里发布了一个适用于以上所有情况的正则表达式。

注意:我已经使用以下正则表达式提取了超过200万个IP地址,没有任何问题。

(?:(?:1\d\d|2[0-5][0-5]|2[0-4]\d|0?[1-9]\d|0?0?\d)\.){3}(?:1\d\d|2[0-5][0-5]|2[0-4]\d|0?[1-9]\d|0?0?\d)

你能详细说明一下你的正则表达式模式吗? - Mohammad Zain Abbas
@MohammadZainAbbas。我认为这将是一个很长的回复。请随意享受这个交互式解释-> https://regexr.com/4r3j3 - m3nda

2

从日志中查找IP地址的最简单方法。

 s = "<html><head><title>Current IP Check</title></head><body>Current IP Address: 165.91.15.131</body></html>"
 info = re.findall(r'[\d.-]+', s)

代码第42行:info

输出结果为[165.91.15.131]


1
请问您能解释一下 [\d.-]+ 中的 '- after .' 代表什么吗? - rakesh patanga
2
[\d.-]+ will grab any number even if the string doesn't contains IPs, i.e: it will grab the IP and the numbers 1 & 2 in a sentence like 104.108.71.62: has versionsr: 1 vs. 2 - Ricky Levi

1

这就是我做的方式。我认为它非常简洁。

import re
import urllib2

def getIP():
    ip_checker_url = "http://checkip.dyndns.org/"
    address_regexp = re.compile ('\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}')
    response = urllib2.urlopen(ip_checker_url).read()
    result = address_regexp.search(response)

    if result:
            return result.group()
    else:
            return None

get_IP()函数返回一个字符串或者None,表示IP地址。

如果你想要更准确的解析,或者更换网络服务提供商,可以将address_regexp替换为其他正则表达式。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接