我有一个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)
答案 0 :(得分:2)
您应该从第一个正则表达式中删除\s?
(在比赛开始时您实际上并不需要空格),或者如果只想在空格之后进行匹配,请替换为(?<!\S)
或字符串的开头。
真正的问题是第二个正则表达式,其中.
驻留在用+
量化的字符类中。其后的\.
也与.
匹配,并且当字符串中没有匹配的文本时,这将成为问题。这是catastrophic backtracking。
由于您期望的匹配项是整个单词,因此我建议通过以下方法来增强模式:1)添加单词边界,2)使所有相邻的子模式匹配不同类型的字符。
使用
r'\b[A-Za-z0-9._%+-]+@(?:[A-Za-z0-9-]+\.)+[A-Za-z]{2,4}\b'
匹配电子邮件。
请参见(?:[A-Za-z0-9-]+\.)+
部分:它与1个或多个字母数字/连字符的一个或多个重复字符匹配,后跟一个点,并且在该模式之后没有\.
,存在一个字母字符类,因此应该不会像以前那样出现问题。
答案 1 :(得分:0)
所以。我使用>>> string = requests.get('http://www.poffoconsultoria.com.br').text
然后我取了字符串的长度,它是>>> len(strings)
474038
,这是一个很高的值。
因此,对于这样的问题,当您看到正则表达式需要很长时间(确实是在获得页面长度之后)时,您应该在浏览器中访问该页面,然后inspect the page source
当我在浏览器中检查页面时,我发现了以下内容:
第二个正则表达式[A-Za-z0-9._%+-]+
肯定会挂起(真的,要花很长时间),因为它无法量化并且必须搜索这些重要部分。
您需要分块页面或限制正则表达式。或者,如果您怀疑需要返回的内容不会出现在其中,可以编写一个丢弃字典数据的函数;基本上,上面的那些大词典使您发布的正则表达式花费很长时间。
答案 2 :(得分:0)
使用有效的电子邮件
(?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]))