鱼C论坛

 找回密码
 立即注册
查看: 12140|回复: 4

[已解决]爬取代理IP,发现正则表达式的结果不准确?

[复制链接]
发表于 2021-8-25 18:29:19 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 bravsheng 于 2021-8-25 18:31 编辑

大家好,刚学完第57课,小甲鱼讲了IP地址的正则匹配,于是自己动手试着写了一个爬取代理IP的程序。
运行结果:ip地址和端口号都对应找到了!  ^_^
发现问题:但仔细一看,有部分IP的第四段数字只匹配到了百位和十位,这是什么原因呢?
一时半会没想出来  @_@?   求鱼油解惑!
>>> p1.search('237.237.237.237')
<re.Match object; span=(0, 14), match='237.237.237.23'>

代码如下:
import urllib.request
import re
from bs4 import BeautifulSoup
index = 0
url = 'https://www.89ip.cn/index_1.html'
response = urllib.request.urlopen(url)
html = response.read()

soup = BeautifulSoup(html,"html.parser")

p1 = re.compile(r'(([01]{0,1}\d{0,1}\d|2[0-4]\d|25[0-5])\.){3}([01]{0,1}\d{0,1}\d|2[0-4]\d|25[0-5])')
p2 = re.compile(r'(\d){2,5}')
for each in soup.find_all('td'):
    index += 1
    each_ip = str(each)
    m1 = p1.search(each_ip)
    if m1:
        each_port = str(soup.find_all('td')[index])
        m2 = p2.search(each_port)
        print(m1.group() + ':' + m2.group())

运行结果:
60.7.97.130:9999
60.217.64.23:38829  #这里应该是60.217.64.237
60.5.172.20:9999
61.131.45.24:9999
61.131.45.66:9999
202.109.157.62:9000
59.55.162.135:3256
60.185.205.20:3000
27.38.95.21:8118
60.167.135.8:1133
59.55.162.169:3256
27.192.168.131:9000
61.161.27.114:9999
60.168.80.102:1133
58.255.6.139:9999
60.167.134.95:1133
60.168.207.22:1133
59.55.164.23:3256
27.214.48.153:9000
49.81.233.141:8888  
最佳答案
2021-8-25 20:00:37
python 是从左往右判断的,而 search 只要匹配到到字符就会结束
你最后一个
([01]{0,1}\d{0,1}\d|2[0-4]\d|25[0-5])
中的第一段
[01]{0,1}\d{0,1}\d
就能任意匹配了,你看以下下代码:
import re

a = re.search("12","12345")
print(a.group())

p1 = re.compile('([01]{0,1}\d{0,1}\d|2[0-4]\d|25[0-5])')
p2 = re.compile('([01]{0,1}\d{0,1}\d|2[0-4]\d|25[0-5]):')
b = p1.search("237:")
c = p2.search("237:")
print(b.group())
print(c.group())

运行结果:
12
23
237:

这是search的性质决定的,不管有没有匹配完,只要匹配到结果就不会继续匹配了,你把 : 号一起匹配进去就行了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2021-8-25 20:00:37 | 显示全部楼层    本楼为最佳答案   
python 是从左往右判断的,而 search 只要匹配到到字符就会结束
你最后一个
([01]{0,1}\d{0,1}\d|2[0-4]\d|25[0-5])
中的第一段
[01]{0,1}\d{0,1}\d
就能任意匹配了,你看以下下代码:
import re

a = re.search("12","12345")
print(a.group())

p1 = re.compile('([01]{0,1}\d{0,1}\d|2[0-4]\d|25[0-5])')
p2 = re.compile('([01]{0,1}\d{0,1}\d|2[0-4]\d|25[0-5]):')
b = p1.search("237:")
c = p2.search("237:")
print(b.group())
print(c.group())

运行结果:
12
23
237:

这是search的性质决定的,不管有没有匹配完,只要匹配到结果就不会继续匹配了,你把 : 号一起匹配进去就行了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-8-26 09:07:38 | 显示全部楼层
白two 发表于 2021-8-25 20:00
python 是从左往右判断的,而 search 只要匹配到到字符就会结束
你最后一个

噢,谢谢解答! 原来如此,我懂了!  
0~255的范围用或隔开了(0~199|200~249|250~255),只要找到了一个就算找了。
所以找到23也是符合范围的,search就停止查找了。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-8-26 09:11:25 | 显示全部楼层
哈哈,我加了个缩进,匹配成功了!
import urllib.request
import re
from bs4 import BeautifulSoup
index = 0
url = 'https://www.89ip.cn/index_1.html'
response = urllib.request.urlopen(url)
html = response.read()

soup = BeautifulSoup(html,"html.parser")

p1 = re.compile(r'(([01]{0,1}\d{0,1}\d|2[0-4]\d|25[0-5])\.){3}([01]{0,1}\d{0,1}\d|2[0-4]\d|25[0-5])\t')
p2 = re.compile(r'(\d){2,5}')
for each in soup.find_all('td'):
    index += 1
    each_ip = str(each)
    m1 = p1.search(each_ip)
    if m1:
        each_port = str(soup.find_all('td')[index])
        m2 = p2.search(each_port)
        print(m1.group() + m2.group())
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-9-5 22:57:46 | 显示全部楼层
p1 = re.compile(r'(([01]{0,1}\d{0,1}\d|2[0-4]\d|25[0-5])\.){3}(2[0-4]\d|25[0-5]|[01]{0,1}\d{0,1}\d)'),第四位数匹配时,调整一下 “ | ” 顺序就可以找到200以上的数。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-1-13 10:28

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表