我有一个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)发布于 2019-04-12 18:49:27
您应该从第一个regex中删除\s? (在匹配开始时并不真正需要空白),如果只想在空格或字符串开始后匹配,则使用(?<!\S)替换。
真正的问题是第二个正则表达式,其中.驻留在一个用+量化的字符类中。它后面的\.也匹配一个.,这使它在字符串中没有显示匹配文本时出现问题。我是catastrophic backtracking。
由于您期望的匹配是完整的单词,我建议通过添加单词边界来增强模式,2)使所有相邻的子模式匹配不同类型的字符。
使用
r'\b[A-Za-z0-9._%+-]+@(?:[A-Za-z0-9-]+\.)+[A-Za-z]{2,4}\b'来匹配电子邮件。
参见(?:[A-Za-z0-9-]+\.)+部分:它匹配一个或多个字母数字/连字符字符的一个或多个重复,后面跟着一个点,并且在这个模式之后没有\.,有一个alpha字符类,所以应该不会出现像前面那个那样的问题。
发布于 2019-04-12 18:23:10
所以。我在Python27中使用>>> string = requests.get('http://www.poffoconsultoria.com.br').text获取网站数据
然后我取了字符串的长度,它是>>> len(strings) 474038,这是一个非常高的值。
因此,对于这样的问题,当人们看到regex花费了这么长的时间(实际上,在得到页面的长度之后),您应该访问浏览器和inspect the page source中的页面。
当我在浏览器中查看页面时,我发现了以下内容:


第二个regex [A-Za-z0-9._%+-]+肯定会挂起(真的,需要很长时间),因为它是不可量化的,必须搜索那些巨大的部分。
您要么需要对页面进行块处理,要么限制正则表达式。或者,您可以编写一个函数,如果您怀疑需要返回的内容不会出现在这些数据中,就会丢弃字典数据;不过,基本上,上面那些巨大的字典导致您发布的正则表达式花费了很长时间。
发布于 2019-04-12 19:16:15
使用有效电子邮件
(?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]))https://stackoverflow.com/questions/55657116
复制相似问题