删除重复的电子邮件

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) 将禁止在单词 末尾带有pngjpg 等扩展名的所有匹配项(\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)))

【讨论】:

以上是关于删除重复的电子邮件的主要内容,如果未能解决你的问题,请参考以下文章

邮件重复数据删除多个用户

如何删除重复的电子邮件地址 [关闭]

将电子邮件附件保存在硬盘上后,如何以编程方式删除它们[重复]

Java从数组中删除重复项?

196. 删除重复的电子邮箱

删除重复的电子邮箱