【问题标题】: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 不起作用

标签: python regex email web-scraping scrapy


【解决方案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)))

【讨论】:

    猜你喜欢
    • 2014-05-15
    • 2015-01-24
    • 2015-07-22
    • 2015-05-24
    • 1970-01-01
    • 1970-01-01
    • 2019-12-17
    • 2013-09-04
    • 2013-02-07
    相关资源
    最近更新 更多