Разбор почтовых адресов в Python
Я пытаюсь разобрать URL-адреса mailto в хороший объект или словарь, который включает subject
, body
и т. д. Мне кажется, я не могу найти библиотеку или класс, который бы этого достиг - Знаете ли вы что-нибудь?
mailto:me@mail.com?subject=mysubject&body=mybody
8 ответов
Похоже, вы можете просто написать свою собственную функцию для этого.
Редактировать: вот пример функции (написана нубом Python).
Редактировать 2, очистка сделать для обратной связи:
from urllib import unquote
test_mailto = 'mailto:me@mail.com?subject=mysubject&body=mybody'
def parse_mailto(mailto):
result = dict()
colon_split = mailto.split(':',1)
quest_split = colon_split[1].split('?',1)
result['email'] = quest_split[0]
for pair in quest_split[1].split('&'):
name = unquote(pair.split('=')[0])
value = unquote(pair.split('=')[1])
result[name] = value
return result
print parse_mailto(test_mailto)
Вы можете использовать urlparse и parse_qs для разбора URL с mailto как схемой. Имейте в виду, что в соответствии с определением схемы:
mailto:me@mail.com,you@mail.com?subject=mysubject
идентично
mailto:?to=me@mail.com&to=you@mail.com&subject=mysubject
Вот пример:
from urlparse import urlparse, parse_qs
from email.message import Message
url = 'mailto:me@mail.com?subject=mysubject&body=mybody&to=you@mail.com'
msg = Message()
parsed_url = urlparse(url)
header = parse_qs(parsed_url.query)
header['to'] = header.get('to', []) + parsed_url.path.split(',')
for k,v in header.iteritems():
msg[k] = ', '.join(v)
print msg.as_string()
# Will print:
# body: mybody
# to: me@mail.com, you@mail.com
# subject: mysubject
Ядро urlparse lib выполняет меньше, чем звездную работу с mailtos, но отправляет вас на полпути:
In [3]: from urlparse import urlparse
In [4]: urlparse("mailto:me@mail.com?subject=mysubject&body=mybody")
Out[4]: ParseResult(scheme='mailto', netloc='', path='me@mail.com?subject=mysubject&body=mybody', params='', query='', fragment='')
РЕДАКТИРОВАТЬ
Небольшое исследование раскопает эту тему. Итог: парсинг Python URL сосет.
Вот решение с использованием модуля re...
import re
d={}
def parse_mailto(a):
m=re.search('mailto:.+?@.+\\..+?', a)
email=m.group()[7:-1]
m=re.search('@.+?\\..+?\\?subject=.+?&', a)
subject=m.group()[19:-1]
m=re.search('&.+?=.+', a)
body=m.group()[6:]
d['email']=email
d['subject']=subject
d['body']=body
Предполагается, что он в том же формате, что и вы. Возможно, вам придется внести изменения, чтобы лучше соответствовать вашим потребностям.
Мне нравится ответ Александра, но он на Python 2! Теперь мы получаемurlparse()
иparse_qs()
отurllib.parse
. Также обратите внимание, что сортировка заголовка в обратном порядке размещает его в следующем порядке: в, из, тело.
from email.message import Message
from pathlib import Path
from urllib.parse import parse_qs, urlparse
url = Path("link.txt").read_text()
msg = Message()
parsed_url = urlparse(url)
header = parse_qs(parsed_url.query)
header["to"] = header.get("to", []) + parsed_url.path.split(",")
for k, v in sorted(header.items(), reverse=True):
print(f"{k}:", v[0])
Я просто использую это как одноразовый, когда я использовалmsg.as_string()
Я получил некоторые странные результаты, поэтому я просто пошел со строкой. Значения представляют собой списки одного значения, поэтому я обращаюсь к 0-й записи, чтобы сделать ее строкой.
import urllib
query = 'mailto:me@mail.com?subject=mysubject&body=mybody'.partition('?')[2]
print dict((urllib.unquote(s).decode('utf-8') for s in pair.partition('=')[::2])
for pair in query.split('&'))
# -> {u'body': u'mybody', u'subject': u'mysubject'}
Вы должны использовать специальную библиотеку, как это
https://pypi.python.org/pypi/urlinfo
и внести свой вклад и создать проблему, чтобы сделать Python лучше;)
PS Не использует решение Роберта Питерса, но не работает должным образом. Также с помощью регулярного выражения используется супер BFG Gun, чтобы получить маленькую птичку.