繁体   English   中英

Python re.findall挂在某些网站上

[英]Python re.findall hangs on certain websites

我有一个python脚本可以循环浏览网站/域列表,以从我的客户网站中删除电话和电子邮件,其中99%的网站中没有问题,并且可以正常工作。 一些网站只是挂起,甚至无法强制中断操作,就像它处于一个疯狂的循环中一样。 下面举一个例子。 有人可以帮助我改善或解决此问题吗?

import requests,re

try:   
    r = requests.Session()
    f = r.get('http://www.poffoconsultoria.com.br', verify=False, allow_redirects=False,timeout=(5,5) )
    s = f.text                  
    tels = set(re.findall(r"\s?\(?0?[1-9][1-9]\)?[-\.\s][2-5]\d{3}\.?-?\s?\d{4}",s))
    emails = set(re.findall(r"[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,4}",s))
    print(tels)
    print(emails)
except Exception as e:
    print(e)

您应该删除\\s? 从第一个正则表达式开始(在比赛开始时您实际上并不需要空格),或者如果只想在空格或字符串开始之后进行匹配,则替换为(?<!\\S)

真正的问题在于第二个正则表达式where . 驻留在用+量化的字符类中。 \\. 其后还匹配一个. 当字符串中没有匹配的文本时,这将成为一个问题。 这是灾难性的回溯

由于您期望的匹配项是整个单词,因此我建议通过以下方法来增强模式:1)添加单词边界,2)使所有相邻的子模式匹配不同类型的字符。

采用

r'\b[A-Za-z0-9._%+-]+@(?:[A-Za-z0-9-]+\.)+[A-Za-z]{2,4}\b'

匹配电子邮件。

请参阅(?:[A-Za-z0-9-]+\\.)+部分:它匹配一个或多个1个或多个字母数字/连字符的重复,后跟一个点,并且没有\\. 在此模式之后,有一个alpha字符类,因此应该不会像以前那样存在问题。

所以。 我在Python27中使用>>> string = requests.get('http://www.poffoconsultoria.com.br').text获得了很好的网站数据

然后,我取了字符串的长度,然后是>>> len(strings) 474038这确实是一个很高的值。

因此,对于此类问题,当您看到正则表达式需要很长时间(确实是在获得页面长度之后)时,您应该在浏览器中访问该页面并inspect the page source

当我在浏览器中检查页面时,我发现了以下内容:

在此处输入图片说明

在此处输入图片说明

第二个正则表达式[A-Za-z0-9._%+-]+肯定会挂起(真的,要花很长时间),因为它无法量化,并且必须搜索那些巨大的部分。

您要么需要分页页面,要么限制正则表达式。 或者,如果您怀疑需要返回的内容不会出现在其中,可以编写一个丢弃字典数据的函数; 但是,基本上,上述那些大词典使您发布的正则表达式花费很长时间。

使用有效的电子邮件

(?i)(?:("[^"\\]*(?:\\.[^"\\]*)*"@)|((?:[0-9a-z](?:\.(?!\.)|[-!#$%&'*+/=?^`{}|~\w])*)?[0-9a-z]@))(?:(\[(?:\d{1,3}\.){3}\d{1,3}\])|((?:[0-9a-z][-\w]*[0-9a-z]*\.)+[a-z0-9][-a-z0-9]{0,22}[a-z0-9]))

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM