Python 3 - 从动态网页中提取IP地址和端口号

时间:2017-09-29 11:45:15

标签: python-3.x

我想从此链接中提取IP地址和端口号。这是我的Python代码: http://spys.one/free-proxy-list/FR/

import urllib.request
import re

url = 'http://spys.one/free-proxy-list/FR/'

req = urllib.request.Request(url, headers={'User-Agent': 'Mozilla/5.0'})
html = urllib.request.urlopen(req).read().decode('utf-8')

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

# ip = re.findall( r'[0-9]+(?:\.[0-9]+){3}:[0-9]+[0-9]',html)  # This is also not working

print (ip)

输出 ['37 .59.0.139','212.47.239.185','85 .248.227.165','167.114.250.199','51 .15.86.160','212.83.164.85','82 .224.48.173']

我只获得IP地址,但没有端口号。

我期待这样的事情 - '37 .59.0.139:17658'

2 个答案:

答案 0 :(得分:0)

首先,你的正则表达方式有点不可思议:你有(?:,你可能意味着(:?。不确定前者意味着什么,但后者意味着零或一:

您的正则表达式仅查找按:.分割的四个数字分组。您最多需要五组数字:0.0.0.0:0000 =五个组。试试这个:

re.findall( r'([0-9]{1,3}\.){3}[0-9]{1,3}(:[0-9]{2,4})?'
  • [0-9]{1,3} = 1到3位数之间
  • \. =一段时间(已转义,因为.表示“任何字符”)
  • {3} =上述内容需要重复三次
  • (:[0-9]{2,4})冒号后跟一个长度为2到4个字符的数字序列。 这是您的端口。
  • ?该端口是可选的,它可以在那里,也可以不在。

答案 1 :(得分:0)

您的代码不起作用,因为 - 除了您在其他答案中指出的正则表达式的几个问题之外 - 您提供的网站通过执行某些<显示每个IP的端口号基础HTML代码中的em> javascript 。

为了捕获每个IP 其关联的端口号,您首先需要执行javascript以便端口号正确打印在HTML响应中(您可以按照此处的指南进行操作:Web-scraping JavaScript page with Python)。然后,您需要从javascript计算的HTML响应中提取此信息。

通过检查HTML响应,我发现每个端口号前面都有:</font>,后跟<

可以在下面找到工作代码段。我冒昧地稍微修改了您的IP-regex,因为只有某些IP地址与端口号相关联(其他IP与 hostname 列相关并且应该被丢弃) - 即感兴趣的IP是后跟<script字符串的那些。

import dryscrape
import re

url = 'http://spys.one/free-proxy-list/FR/'



#get html with javascript
session = dryscrape.Session()
session.visit(url)
response = session.body()


#capture ip:
IP = re.findall(r'[0-9]+(?:\.[0-9]+){3}(?=<script)',response)

#capture port:
port = re.findall(r'(?<=:</font>)(.*?)(?=\<)',response)

#join IP with ports
IP_with_ports = []
for i in range(len(IP)):
    IP_with_ports.append(IP[i] + ":" + port[i])


print (IP_with_ports)

输出:['178.32.213.128:80','151.80.207.148:80','134.119.223.242:80','37 .59.0.139:17459',...,' 37.59.0.139:17658' ]

请注意,上述代码仅适用于您提供的网站,因为每个网站都有自己的显示数据的逻辑。

相关问题