删除重复的电子邮件
Posted
技术标签:
【中文标题】删除重复的电子邮件【英文标题】:Erase duplicate emails 【发布时间】:2016-08-08 02:13:06 【问题描述】:我正在尝试在 scrapy 中使用正则表达式来查找页面上的所有电子邮件地址。
我正在使用此代码:
item["email"] = re.findall('[\w\.-]+@[\w\.-]+', response.body)
这几乎是完美的:它会抓取所有电子邮件并将它们提供给我。但是我想要的是:它在实际解析之前不会给我重复,即使有多个相同的电子邮件地址。
我收到这样的回复(这是正确的):
'email': ['billy666@stanford.edu',
'cantorfamilies@stanford.edu',
'cantorfamilies@stanford.edu',
'cantorfamilies@stanford.edu',
'footer-stanford-logo@2x.png']
但是我只想显示唯一的地址
'email': ['billy666@stanford.edu',
'cantorfamilies@stanford.edu',
'footer-stanford-logo@2x.png']
如果你想介绍如何只收集电子邮件而不是那个
'footer-stanford-logo@2x.png'
这也很有帮助。
谢谢大家!
【问题讨论】:
为什么要使用正则表达式来解析响应?似乎它可能更适合 xpath 或 css 选择器。使用正则表达式解析 html 通常是个坏主意 因为这是在一个广泛的爬虫中使用的,其中数据将存储在不同的地方。所以没有一个 xpath 不起作用 【参考方案1】:以下是您如何摆脱输出中的欺骗和'footer-stanford-logo@2x.png'
之类的东西:
import re
p = re.compile(r'[\w.-]+@(?![\w.-]*\.(?:png|jpe?g|gif)\b)[\w.-]+\b')
test_str = "'email': ['billy666@stanford.edu',\n 'cantorfamilies@stanford.edu',\n 'cantorfamilies@stanford.edu',\n 'cantorfamilies@stanford.edu',\n 'footer-stanford-logo@2x.png']"
print(set(p.findall(test_str)))
见Python demo
正则表达式看起来像
[\w.-]+@(?![\w.-]*\.(?:png|jpe?g|gif)\b)[\w.-]+\b
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^
见demo
否定的前瞻(?![\w.-]*\.(?:png|jpe?g|gif)\b)
将禁止在单词 末尾带有png
、jpg
等扩展名的所有匹配项(\b
是单词边界,在此情况下,它是一个尾随字边界)。
使用set
可以轻松删除受骗者 - 这是这里最不麻烦的部分。
最终解决方案:
item["email"] = set(re.findall(r'[\w.-]+@(?![\w.-]*\.(?:png|jpe?g|gif)\b)[\w.-]+\b', response.body))
【讨论】:
与(?:png|jpe?g|gif)
很好的接触
不知道为什么,但是当我使用此代码时,它不会提供任何电子邮件,但它仅适用于 item["email"] = set(re.findall('[\w\.-]+@ [\w\.-]+', response.body)) 删除重复项。虽然我很想知道为什么它没有显示在我的结果中。因为我关注了那个演示页面(BTW),它按预期工作:/
抱歉,我添加了 r
前缀来将字符串标记为原始字符串文字。现在,\b
被视为单词边界,而不是退格字符。使用item["email"] = set(re.findall(r'[\w.-]+@(?![\w.-]*\.(?:png|jpe?g|gif)\b)[\w.-]+\b', response.body))
知道了!谢啦!!!!!很高兴知道 r 如何影响它。谢谢你也解释一下。【参考方案2】:
item["email"] = set(re.findall('[\w\.-]+@[\w\.-]+', response.body))
【讨论】:
额外的布朗尼点可以忽略'footer-stanford-logo@2x.png'
。 :) +1 虽然
无需在字符类中转义.
。它确实无助于导入这些 PNG。如果这个或 Thomas 被接受,那么问题将是 Returning unique matches using regex in python 的欺骗。 @idjaw:检查我的答案,我建议一种忽略 PNG 的方法。
感谢 Wiktor,如果是 Dupe,我很抱歉,我不完全理解正则表达式,所以如果得到回答,我很抱歉,我一定不明白
也不完全确定对于 .我从 SO 上的某个人那里得到了这段代码的“部分”,所以如果它不正确,那么感谢您让我知道!【参考方案3】:
你不能只使用一个集合而不是一个列表吗?
item["email"] = set(re.findall('[\w\.-]+@[\w\.-]+', response.body))
如果你真的想要一个列表,那么:
item["email"] = list(set(re.findall('[\w\.-]+@[\w\.-]+', response.body)))
【讨论】:
以上是关于删除重复的电子邮件的主要内容,如果未能解决你的问题,请参考以下文章