LINUX.ORG.RU

[python][proxy] скрипт не ходит через прокси

 ,


0

1

Вот нарыл в инете такой скрипт для забора тем писем с gmail'a, который запускается из conky:

# ======================================================================
# Copyright (C) 2006 Baishampayan Ghose <b.ghose@ubuntu.com>
# Modified 2008 Hunter Loftis <hbloftis@uncc.edu>
# Time-stamp: Mon Jul 31, 2006 20:45+0530
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 as
# published by the Free Software Foundation.
# ======================================================================

import sys
import urllib             # For BasicHTTPAuthentication
import feedparser         # For parsing the feed
import pickle
from textwrap import wrap

_URL = "https://mail.google.com/gmail/feed/atom"

uname = sys.argv[1]
password = sys.argv[2]
maxlen = sys.argv[3]
filename = "~/scripts/subjects"

urllib.FancyURLopener.prompt_user_passwd = lambda self, host, realm: (uname, password)

def auth():
    '''The method to do HTTPBasicAuthentication'''
    opener = urllib.FancyURLopener()
    f = opener.open(_URL)
    feed = f.read()
    return feed


def readmail(feed, maxlen):
        '''Parse the Atom feed and print a summary'''
        atom = feedparser.parse(feed)
#       print '${color1} %s new emails:\n' % (len(atom.entries))
        file = open(filename, 'w')
        data ='${color1}%s new emails:\n' % (len(atom.entries))
        file.write(data)
        for i in range(min(len(atom.entries), maxlen)):
#               print '          ${color2}%s' % atom.entries[i].title.encode('utf-8')
                data =' ${color2}' + atom.entries[i].title.encode('utf-8') + '\n'
                file.write(data)
#uncomment the following line if you want to show the name of the sender
#               print '          ${color2}%s' % atom.entries[i].author
        if len(atom.entries) > maxlen:
                print ' ${color}more...'

if __name__ == "__main__":
    f = auth()  # Do auth and then get the feed
    readmail(f, int(maxlen)) # Let the feed be chewed by feedparser
#file.close()

Первый вопрос: Почему закомменченные строки в ф-ии readmail не выводят в консоль читаемый утф8, а лишь его коды, хоть я и сделал encode. Пришлось выводить в файл сначала, а потом cat этот файл в конки.

Воторой вопрос: На домашнем компе все работает (но через вышеозначенный костыль), но на работе нужно, чтоб скрипт забирал страницу через прокси. Заменяем ф-ию auth на следующее:

def auth():
    '''The method to do HTTPBasicAuthentication'''
    proxy = {'http':'http://10.10.176.177:8181'} // домашний прокси
    opener = urllib.FancyURLopener(proxy)
    f = opener.open(_URL)
    feed = f.read()
    print feed // для дебага, но ничего не выводит, тк через прокси не проходит :)
    return feed

Не работает. Что поправить, чтоб через прокси ходил?


Попробуй использовать urllib2

anonymous
()
Ответ на: комментарий от true_admin

Хм... странное дело :)
Раскомментил вывод в консоль с encode и все пучком. Что-то я, видимо, напутал в процессе изысканий.
Первый вопрос снят.
Сейчас попробую с urllib2

err0r
() автор топика
Ответ на: комментарий от Deleted

Я ж говорю, что все уже хорошо с выводом в утф8. Причем, использую encode, а не decode... почему-то.

А вот со вторым вопросом есть кое-какие прояснения. Попробовал забрать какую-нть страницу простым методом без прокси:

import urllib2

response = urllib2.urlopen('https://priemnaya.petrozavodsk-mo.ru/')
html = response.read()
print html

И все ок. Забирается! То есть, видимо, читается переменная окружения http_proxy.

Но как я ни бился, с gmail'ом такое не прокатывает. Конечно, пытаясь авторизоваться. Не работает через liburl, как в первом примере, так и с liburl2 не работает из примера из руководства:

# create a password manager
password_mgr = urllib2.HTTPPasswordMgrWithDefaultRealm()

# Add the username and password.
# If we knew the realm, we could use it instead of ``None``.
top_level_url = "http://example.com/foo/"
password_mgr.add_password(None, top_level_url, username, password)

handler = urllib2.HTTPBasicAuthHandler(password_mgr)

# create "opener" (OpenerDirector instance)
opener = urllib2.build_opener(handler)

# use the opener to fetch a URL
opener.open(a_url)

# Install the opener.
# Now all calls to urllib2.urlopen use our opener.
urllib2.install_opener(opener)

err0r
() автор топика
Ответ на: комментарий от err0r

Могу предположить, что все дело в том, что gmail использует https, а не http. Соответственно и на значение переменной http_proxy ему как-то все равно.

l0k9j8
()
Ответ на: комментарий от err0r

>И все ок. Забирается! То есть, видимо, читается переменная окружения http_proxy.

Прокси, кстати, можно и в коде определять, через сам urllib2

anonymous
()
Ответ на: комментарий от err0r

>Но как я ни бился, с gmail'ом такое не прокатывает.

И, да, если тебе очень хочется - то может проще взять fetchmail и работать уже с ним через скрипт?

anonymous
()

Ужас-то какой - прямо заблудились в трех соснах. Один говорит - «encode», другой - «decode»! Что делать?

Не знаю точно, как в py3k, а в python 2.x дело происходит так - если у нас есть unicode-объект my_unicode_object то получаем следующее:

  • если делаем `print my_unicode_object', то my_unicode_object кодируется в байты с использованием значения sys.stdout.encoding (которое должно по идее соответствовать представлению python о «кодировке терминала»). Если не вышло - UnicodeEncodeError.
  • если делаем `sys.stdout.write(my_unicode_object)' то к my_unicode_object применяется str() (при этом используется значение sys.getdefaultencoding(), например, «ascii»), а то, что получилось, - если получилось, отправляется в stdout

И, наконец, для самых маленьких:

  unicode object -> encode -> bytestring (str)
                  (encoding)
bytestring (str) -> decode -> unicode object

Надо понимать, что, в конечном итоге, в файл (в т.ч. и терминал) пойдут именно байты.

shylent
()
Ответ на: комментарий от baverman

Прошу обратить внимание на:

import urllib2

response = urllib2.urlopen('https://priemnaya.petrozavodsk-mo.ru/')
html = response.read()
print html

Видно, что https? Не? И работает. А с гмэйлом нет. Хотя на гмэйле аутентифицироваться надо. И, возможно, не работает как раз аутентификация через https. То есть я ее не умею готовить.

Спасибо, anonymous, fetchmail уж слишком здоровый, хотя расширенный функционал дает. Хотелось бы обойтись без него.

В скрипте уже пытался определять прокси, никак не выходит. Питон я первый раз вижу, хоть и опыт программинга большой.

Короче, сами попробуйте из-за прокси этим скриптом вытянуть свою почту (темы) с гмэйла. Может у кого удастся.

err0r
() автор топика
Ответ на: комментарий от true_admin

разве я не так сказал? :) decode возвращает unicode пригодное для print

Как сказать? Тут даже вопрос не в том, что decode возвращает, а в том, к чему decode применяется.

К примеру, если применить decode «в лоб» к unicode object, то может получиться так:

>>> a = u'фубар'
>>> a
u'\u0444\u0443\u0431\u0430\u0440'
>>> a.decode('utf-8')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Python26\lib\encodings\utf_8.py", line 16, in decode
    return codecs.utf_8_decode(input, errors, True)
UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-4: ordinal not in range(128)

WTF? Откуда UnicodeEncodeError, я же использовал decode, кажется, нет? Понятно, что декодировать unicode object просто-напросто нельзя, т.к. декодировать там нечего. Поэтому к объекту применяется str(), который использует defaultencoding (т.е. 'ascii'), чтобы кодировать объект в байты, к которым можно будет потом применить decode. Такие дела.

Честно говоря, мой предыдущий пост, в основном, относился к топикстартеру, так что можете не принимать его особо на свой счет. Ну, если, конечно же, у вас проблем с юникодом нет.

shylent
()
Ответ на: комментарий от baverman

Ага, пригодное, особенно если defaultencoding — ascii.

Это уже проблема print и юзера который не выставил локаль.

true_admin ★★★★★
()
Ответ на: комментарий от shylent

Откуда UnicodeEncodeError, я же использовал decode, кажется, нет?

ой, я и забыл про это. Тогда ты прав. Слава богу в py3k разобрались с этим бардаком.

true_admin ★★★★★
()
Ответ на: комментарий от true_admin

Да что вы прицепились к юникоду-то :) Уже все решено давно, хоть и спасибо за доп инфу.
Лучше с фетчем с гмэйла помогите.

err0r
() автор топика
Ответ на: комментарий от err0r

> Да что вы прицепились к юникоду-то

Если бы не прицепились, вы бы так до конца жизни и гадали, где там что вызывать - encode или decode. А надо не гадать, а знать.

shylent
()
Ответ на: комментарий от shylent

Shylent, ты прав, конечно, надо знать. И я вам благодарен.
А теперь к делу... :)

err0r
() автор топика
Ответ на: комментарий от shylent

>К примеру, если применить decode «в лоб» к unicode object, то может получиться так:

Имхо, главное, что стоит упоминать в каждом руководстве по питону - то, что питоновский unicode не имеет никакого отношения к utf-8. Люди, вдохновившись всегда работающим print-ом в линуксе, совершенно упускают этот факт. Оттуда и постоянные проблемы с этими encode-decode

anonymous
()
Ответ на: комментарий от err0r

Надо буит Следжа Хаммера пересмотреть. Вспомнить детство.

*cheers*

true_admin ★★★★★
()
Ответ на: комментарий от anonymous

Полностью согласен. Есть, конечно вот эта страница, но там, прямо скажем, очень много написано совершенно «не по делу», т.е. информация вроде бы полезная, но обычно человеку, у которого «русские буковки не печатаются», просто не хватит терпения все это прочитать.

shylent
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.