我有一个代码可以抓取一百万个网站并检测其主页上的联系信息。
由于某些原因,当我运行代码时,它会卡住并且在抓取大约60k请求后不会继续,我将我的数据库中的网站网址标记为status=done
我已经多次运行代码,但却遇到了大约60k的请求。
它不会卡在某个网站上。
这是正在使用的正则表达式
emails = re.findall('[\w\.-]+@[\w-]+\.[\w\.-]+', lc_body)
mobiles = re.findall(r"(\(?(?<!\d)\d{3}\)?-? *\d{3}-? *-?\d{4})(?!\d)|(?<!\d)(\+\d{11})(?!\d)", lc_body)
abns = re.findall('[a][-\.\s]??[b][-\.\s]??[n][-\:\.\s]?[\:\.\s]?(\d+[\s\-\.]?\d+[\s\-\.]?\d+[\s\-\.]?\d+)', lc_body)
licences = re.findall(r"(Licence|Lic|License|Licence)\s*(\w*)(\s*|\s*#\s*|\s*.\s*|\s*-\s*|\s*:\s+)(\d+)", lc_body, re.IGNORECASE)
我的想法是licences
正则表达式导致问题,我该如何简化?如何删除回溯?
我想找到所有可能的许可证号码。
它可以是License No: 2543
,License: 2543
,License # 2543
,License #2543
,License# 2543
以及许多其他组合。
答案 0 :(得分:1)
问题是由第三组造成的:(\s*|\s*#\s*|\s*.\s*|\s*-\s*|\s*:\s+)
- 所有替代方案都以\s*
开头。这会导致大量冗余回溯,因为这些替代方案可以在字符串中的相同位置匹配。 最佳做法是在交替组中使用在同一位置不匹配的替代方案。
现在,看一下你需要匹配的字符串,我建议使用
Lic(?:en[cs]e)?(?:\W*No:)?\W*\d+
请参阅regex demo
使模式更具体和线性,尽可能多地删除alternations,使用optional non-capturing groups和字符类。
<强>详情:
Lic(?:en[cs]e)?
- Lic
后跟1或0次出现((?:...)?
是可选的non-capturing group,因为?
量词匹配量化的1或0次出现ence
或ense
(字符类[sc]
匹配s
或c
并且效率高于(s|c)
)(?:\W*No:)?
- 一个非捕获组,匹配1或0次出现的0 +非单词字符(含\W*
),后跟No:
子字符串\W*
\d+
- 一位或多位数。