Python re.findall挂在某些网站上

时间:2019-04-12 17:45:21

标签: python regex python-requests

我有一个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)

3 个答案:

答案 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

在Python27中获得了很好的网站数据

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

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

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

enter image description here

enter image description here

第二个正则表达式[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]))