Как выглядит этот Perl XML-фильтр в Python?

1
curl -u $1:$2 --silent "https://mail.google.com/mail/feed/atom" | perl -ne 'print "\t" if /<name>/; print "$2\n" if /<(title|name)>(.*)<\/\1>/;'

У меня есть оболочка script, которая получает фид Atom с аргументами командной строки для имени пользователя и пароля. Мне было интересно, возможно ли это в Python, и если да, то как бы я это сделал. Атомный канал - это просто обычный XML.

  • 2
    Сам Perl не имеет смысла. print "$2\n" if /(.*)/; говорит «напечатать вторую группу захвата в регулярном выражении», но там есть только одна группа захвата. Там никогда не будет второй матч группы ...
Теги:
curl
email

2 ответа

3
Лучший ответ

Python не поддается сжатию одного лайнера, а также Perl. Это происходит в основном по трем причинам:

  • С Perl пробелы незначительны практически во всех случаях. В Python пробелы очень значительны.
  • Perl имеет несколько полезных ярлыков для одного лайнера, например perl -ne или perl -pe, который помещает неявный цикл вокруг строки кода,
  • большой кузов-груз-культ Perl один лайнер, чтобы делать полезные вещи.

Что все сказано, этот питон близок к тому, что вы разместили в Perl:

curl -u $1:$2 --silent "https://mail.google.com/mail/feed/atom" | python -c ' 
import sys
for s in sys.stdin:
    s=s.strip()
    if not s: print '\t',
    else: print s
' 

Немного сложно сделать лучше, потому что, как указано в моем комментарии, Perl, который вы опубликовали, является неполным. У вас есть:

perl -ne 'print "\t" if //; print "$2\n" if /(.*)/;'

Что эквивалентно:

LINE:
while (<>) {
  print "\t" if //;         # print a tab for a blank line
  print "$2\n" if /(.*)/;   # nonsensical. Print second group but only 
                            # a single match group defined...
}

Edit

Хотя тривиально переписать этот Perl в Python, вот что-то лучше:

#!/usr/bin/python
from xml.dom.minidom import parseString
import sys

def get_XML_doc_stdin(f):
    return xml.dom.minidom.parse(f)

def get_tagged_data2(tag, index=0):    
    xmlData = dom.getElementsByTagName(tag)[index].firstChild.data
    return xmlData

data=sys.stdin.read()
dom = parseString(data)

ele2=get_tagged_data2('title')
print ele2

count=int(get_tagged_data2('fullcount'))
print count,"New Messages:"

for i in range(0,count):
    nam=get_tagged_data2('name',i)
    email=get_tagged_data2('email',i)
    print "  {0}: {1} <{2}>".format(i+1,nam,email)

Теперь сохраните это в текстовом файле, запустите chmod +x на нем, а затем:

curl -u $1:$2 --silent "https://mail.google.com/mail/feed/atom" | 
/path/pythonfile.py

Он производит это:

Gmail - Inbox for [email protected]
2 New Messages:
  1: bob smith <[email protected]>
  2: Google Alerts <[email protected]>

изменить 2 И если вам это не нравится, вот фильтр линии Python 1:

curl -u $1:$2 --silent "https://mail.google.com/mail/feed/atom" |python -c ' 
import sys, re
for t,m in re.findall(r"<(title|name)>(.*)<\/\1>",sys.stdin.read()):
    print "\t",m
'
  • 0
    просто исправил perl - многое из этого не отображалось ... странно. я обнаружил, что тег <pre> имеет проблемы с
  • 0
    '<внутри, но если бы вы могли обновить свой ответ, это было бы здорово
1

Вы можете использовать "открыватель URL" из стандартного модуля Python urllib2 с обработчиком аутентификации. Например:

#!/usr/bin/env python

import getpass
import sys
import urllib2

def main(program, username=None, password=None, url=None):

    # Get input if any argument is missing
    username = username or raw_input('Username: ')
    password = password or getpass.getpass('Password: ')
    url = url or 'https://mail.google.com/mail/feed/atom'

    # Create password manager
    password_mgr = urllib2.HTTPPasswordMgrWithDefaultRealm()
    password_mgr.add_password(None, url, username, password)

    # Create HTTP Authentication handler and URL opener
    authhandler = urllib2.HTTPBasicAuthHandler(password_mgr)
    opener = urllib2.build_opener(authhandler)

    # Fetch URL and print content
    response = opener.open(url)
    print response.read()

if __name__ == '__main__':
    main(*sys.argv)

Если вы хотите также извлечь информацию из фида, вы должны проверить, как Защищенные паролем фиды с помощью feedparser.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню