Hatena::Grouppython

zorioの日記

2010-04-01

webページをevernoteにクリップするスクリプト

22:53

順に、

という操作を行う。

htmlの解析はBeautifulSoupを使用。

http://www.crummy.com/software/BeautifulSoup/

# -*- encoding: utf-8 -*-

import urllib, urllib2, cookielib, re, logging
from BeautifulSoup import BeautifulSoup

LOGIN_URL = "https://www.evernote.com/Login.action"
POST_URL = "http://www.evernote.com/clip.action"
USERNAME = 'xxxxxxxxxx'
PASSWORD = 'yyyyyyyyyyyyyy'
NOTEBOOK_GUID = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'

def clip(url, comment, title):
    logging.debug(url)
    logging.debug(title)
    logging.debug(comment)

    tags = ''

    soup = BeautifulSoup(urllib2.urlopen(url).read())
    body = ''
    if soup.body:
        body = unicode(soup.body).encode('utf-8')
    
    if isinstance(title, unicode):
        title = title.encode('utf-8')
    
    if isinstance(comment, unicode):
        comment = comment.encode('utf-8')
    
    cj = cookielib.CookieJar()
    cjhdr = urllib2.HTTPCookieProcessor(cj)
    opener = urllib2.build_opener(cjhdr)

    soup = BeautifulSoup(opener.open(LOGIN_URL).read())
    srcpage = soup.find('input', {'name': '_sourcePage'})
    fp = soup.find('input', {'name': '__fp'})

    opener.open(LOGIN_URL, urllib.urlencode({
        '_sourcePage': srcpage['value'], 
        '__fp': fp['value'], 
        'username': USERNAME, 
        'password': PASSWORD, 
        'login': 'Sign in'
    }))

    param = urllib.urlencode({
      'url': url,
      'body': body, 
      'title': title, 
      'format': 'microclip', 
      'quicknote': 'true'
    })
    logging.debug(param)
    r = opener.open(POST_URL, param)

    soup = BeautifulSoup(r.read())
    
    sel = soup.findAll('select', {'name': 'notebookGuid', 'value': NOTEBOOK_GUID})
    if sel == None:
        raise ValueError('Not logged in')
    
    param = urllib.urlencode({
        'title': title, 
        'tags': tags,
        'notebookGuid': NOTEBOOK_GUID, 
        'comment': comment, 
        'url': url, 
        'fullPage': 'true', 
        'saveQuicknote': 'save',
        'format': 'microclip',
        'body': body,
        '_sourcePage': soup.find('input', {'name': '_sourcePage'})['value'], 
        '__fp': soup.find('input', {'name': '__fp'})['value']
    })
    logging.debug(param)
    r = opener.open(POST_URL, param)
    r.read()

最後に404が出てコケるんだが、登録は出来ている。

で、これをgoogle appengineで動かそうとすると、最後のPOSTでタイムアウトするみたいでうまく動かない。

詳細を追いかけるのは断念。

BayleBayle2011/07/27 05:51Superbly illuminating data here, tahnks!

jnzegblyrdujnzegblyrdu2011/07/27 21:41weNSb5 <a href="http://krbkzqmkljfc.com/">krbkzqmkljfc</a>

qfqpooagqfqpooag2011/07/28 22:53C3viZf , [url=http://zhafeamtgtok.com/]zhafeamtgtok[/url], [link=http://gmfcupcpvadr.com/]gmfcupcpvadr[/link], http://vkqpcbiaklwc.com/

hmoxqkumvhmoxqkumv2011/07/29 21:17vYvyuZ <a href="http://lzadcelykvcn.com/">lzadcelykvcn</a>

bugphznqbugphznq2011/07/31 00:46k26xuw , [url=http://oygclwgmvvgn.com/]oygclwgmvvgn[/url], [link=http://fqddlcwejkss.com/]fqddlcwejkss[/link], http://tlqpxytycmyd.com/

nn2012/01/30 04:50GAEの場合HTTPSによるGETは許可されてもPOSTは許可されてないらしいです。

CynthiaCynthia2012/12/09 20:26I don't know who you wrote this for but you helped a brtoher out.

ybsoveyhybsoveyh2012/12/10 18:21ciMySw <a href="http://wewmwxmicxme.com/">wewmwxmicxme</a>

vcklzyvcklzy2012/12/12 03:31FXVGv9 , [url=http://ikcgtjtdajbr.com/]ikcgtjtdajbr[/url], [link=http://qjppgbfwiksg.com/]qjppgbfwiksg[/link], http://cdxfhdfmugku.com/

frtfmgijjsfrtfmgijjs2014/02/07 19:26rxlscqzuipo, <a href="http://www.kbgfjbmoix.com/">ifgwsikrgy</a>

ljyynztkhsljyynztkhs2014/02/10 06:56cygvpqzuipo, http://www.ouzgqdnjwc.com/ dlnxtovlgh

dxszpphmindxszpphmin2014/02/12 19:57sowtlqzuipo, <a href="http://www.xnblubwvke.com/">njezxztfvd</a> , [url=http://www.udvxiienhr.com/]blaxbobmnb[/url], http://www.vqjngciqal.com/ njezxztfvd

2010-03-22

文字列処理

13:43

同じ内容のリテラルでも、2回書いたら別のインスタンスになった

# -*- encoding: utf-8 -*-

str1 = "String is immutable"
str2 = "String is immutable"
print str1 == str2 # => True
print str1 is str2 # => False
print id(str1), id(str2) # => 43, 44

文字列を分割して配列に保存

# -*- encoding: utf-8 -*-

delim = ","
source = "abc, def, ghi, ,"

# string.splitを使う
print source.split(delim) # => ['abc', ' def', ' ghi', ' ', '']

# 正規表現で自前で分割してみる
import re
reg = re.compile(delim)
list = []
end = 0
for m in reg.finditer(source):
  list.append(source[end:m.start()])
  end = m.end()
list.append(source[end:])

print list # => ['abc', ' def', ' ghi', ' ', '']

print list == source.split(delim) # => True

axkvduthzpaxkvduthzp2011/03/15 20:57vzOLlq <a href="http://gsxiwyekxxxi.com/">gsxiwyekxxxi</a>, [url=http://tvemvemltviq.com/]tvemvemltviq[/url], [link=http://riebovoddrkr.com/]riebovoddrkr[/link], http://mwkcikamwzat.com/

FrancineFrancine2012/12/07 16:08A good many valubales you've given me.

nuwelgbsjnuwelgbsj2012/12/08 16:50c22DyI <a href="http://mbscsbzmsgwf.com/">mbscsbzmsgwf</a>

bxkplcwbxkplcw2012/12/09 22:116XRJKT , [url=http://himmxvrjvlqo.com/]himmxvrjvlqo[/url], [link=http://wbaxnjnxzpal.com/]wbaxnjnxzpal[/link], http://fpfzrwskrjms.com/

uofixknmtieuofixknmtie2012/12/11 13:373QT4iY <a href="http://fvbekztndcrj.com/">fvbekztndcrj</a>

2010-03-21

classの中と外でdefの挙動が違うのかな

23:18

インスタンスメソッドを後から他の変数に代入しても動く

# -*- encoding: utf-8 -*-
class C:
  def __init__(self, n):
    self.n = n
  
  def method(self, x):
    return self.n ** x

ins = C(2)
print ins.method(3) # => 2 ** 3 = 8

m = ins.method #ここでメソッドをmに代入
ins = C(3)
print ins.method(3) # => 3 ** 3 = 27

print m(3) # => 8

クラスの外で定義した関数をそのまま代入しても、インスタンスメソッドには出来ないみたい

# -*- encoding: utf-8 -*-
class Hoge:
  def __init__(self, n):
    self.x = n

def Method(self):
  return self.x ** 2

hoge1 = Hoge(3)
hoge1.method = Method

hoge1.method() # => 9 と動いて欲しい。
Traceback (most recent call last):

  File "C:\Users\*****\Desktop\temp.py", line 11, in C:\Users\*****\Desktop\temp.py

TypeError: Method() takes exactly 1 argument (0 given)

new.instancemethodを使えば出来るそうで。これは何をしてるんだろうな。

http://www.python.jp/doc/2.4/lib/module-new.html

参考:

http://lightson.dip.jp/zope/ZWiki/015_e7_89_b9_e7_95_b0_e3_83_a1_e3_82_bd_e3_83_83_e3_83_89

クラスに追加したら出来た

# -*- encoding: utf-8 -*-
class Hoge:
  def __init__(self, n):
    self.x = n

def Method(self):
  return self.x ** 2

hoge1 = Hoge(3)
Hoge.method = Method

print hoge1.method() # => 9
print Hoge.method(hoge1) # => 9

クラス定義の問題じゃなくて、インスタンスになにかあるんだな、きっと。

スタティックメソッドとクラスメソッド

22:30

参考:

http://jutememo.blogspot.com/2008/09/python-classmethod-staticmethod.html

スタティックメソッドの場合、メソッドを定義したクラスにしかアクセスできない

# -*- encoding: utf-8 -*-
class Base:
  isInitialized = False
  @staticmethod
  def Initialize():
    if Base.isInitialized == False:
      print "This is initialized now"
      Base.isInitialized = True
    else:
      print "This is already initialized"
    

class Derived1(Base):
  pass
  
class Derived2(Base):
  pass

Derived1().Initialize()
Derived1().Initialize()
Derived2().Initialize()
Derived2().Initialize()
実行結果:最初に作ったDerived1の時しか実行されない
This is initialized now
This is already initialized
This is already initialized ←ここが違い
This is already initialized

クラスメソッドは、実際に実行されたクラスにアクセスできる

# -*- encoding: utf-8 -*-
class Base:
  isInitialized = False

  @classmethod
  def Initialize(cls):
    if cls.isInitialized == False:
      print str(cls) + " is initialized now"
      cls.isInitialized = True
    else:
      print str(cls) + " is already initialized"

class Derived1(Base):
  pass
  
class Derived2(Base):
  pass

Derived1().Initialize()
Derived1().Initialize()
Derived2().Initialize()
Derived2().Initialize()
実行結果:最初のDerived1、最初のDerived2でそれぞれ実行される。
__main__.Derived1 is initialized now
__main__.Derived1 is already initialized
__main__.Derived2 is initialized now  ←ここが違い
__main__.Derived2 is already initialized

サブクラスでクラス変数初期化をやりたいんだけどその初期化の処理は基底クラスに書きたい、って事が実際にあったので、そういう時に便利なんじゃないかな。

PankajPankaj2012/09/21 11:00AFAIC that's the best aneswr so far!

afupeujpdrafupeujpdr2012/09/21 23:46MTalJW <a href="http://ycxcqxoejgee.com/">ycxcqxoejgee</a>

dqhbxkdqhbxk2012/09/22 11:38o1dD2K , [url=http://yvhtscoxhqvw.com/]yvhtscoxhqvw[/url], [link=http://ebwkccusvzdq.com/]ebwkccusvzdq[/link], http://gjkculbqdbcg.com/

ibhngctibhngct2012/09/23 05:20RLMPm7 <a href="http://kukgevixdgyr.com/">kukgevixdgyr</a>

egncghfcbegncghfcb2012/09/23 17:029nRjzr , [url=http://maxnbuutmooq.com/]maxnbuutmooq[/url], [link=http://gienvxcvupak.com/]gienvxcvupak[/link], http://rcrbtronnqss.com/

2010-03-20

やるぞー

00:59

簡単な内容でも書きながら、手になじむようにしていこうかと。

id:rubycoさんの日記などを元ネタにしつつ。

リテラル

01:06

http://lightson.dip.jp/zope/ZWiki/001_e3_83_aa_e3_83_86_e3_83_a9_e3_83_ab

list=[1,2,3]
tuple=(1,2,3)
dict={'A': 'a', 'B': 'b'}

演算子

01:09

==は同値性、isはオブジェクトの同一性を比較する。

javaで言う==と.equalsの違いみたいなものかな。

import copy

a=range(5)
b=copy.copy(a)
print a == b # => True
print a is b # => False

c = a
print a == c # => True
print a is c # => True

変数と定数

01:35

http://lightson.dip.jp/zope/ZWiki/003_e5_a4_89_e6_95_b0_e3_81_a8_e5_ae_9a_e6_95_b0

参照はLEGBの順

def outer(s):
  value = s + ":hoge"
  def inner():
    return value
  
  return inner()

print outer("aaa") # aaa:hoge

代入は常にローカル

def outer(a, b):
  outervalue1 = a
  outervalue2 = a
  def inner(b):
    outervalue1 = b
    innervalue = b
    print innervalue # => B
    print outervalue1 # => B
    print outervalue2 # => A

  inner(b)
  print outervalue1 # => A ←Bになったりしない
  print outervalue2 # => A

outer("A", "B")

つまり、代入は常にローカルスコープに対して行われる、と。

python3では、nonlocalって書けば一個外側のスコープを対象に出来るのか。


属性はインスタンスが優先で、クラス属性は隠蔽される。

class MyClass:
  class_property = 0
  common_property = -1
  def __init__(self):
    self.inst_property = 1
    self.common_property = 2

ins = MyClass()
print ins.class_property # => 0
print ins.inst_property # => 1
print ins.common_property # => 2

処理フローの制御

01:51

if cond_a:
  ...
elif cond_b:
  ...
else:
  ...

whileを使った制御

x = 0
while x < 10:
  print x
  x += 1

0
1
2
3
4
5
6
7
8
9

forを使った制御

for x in ['a', 'bb', 'ccc']:
  print x, len(x)
a 1
bb 2
ccc 3

zipを使うと複数を同時に回せる

for x, y in zip([1, 2, 3], ['a', 'b', 'c']):
  print x, y
1 a
2 b
3 c

メソッド呼び出し

02:13

キーワード引数の使用

# -*- encoding: utf-8 -*-
def funcwithnamedargs(a=1, b=2):
  print a
  print b

# 引数を省略
funcwithnamedargs()

# 名前なしで引数を指定
funcwithnamedargs(3, 4)

# 名前付きで引数を指定
funcwithnamedargs(b = 6, a = 5)

# リストを展開して呼び出すときは *
funcwithnamedargs(*[7, 8])

# 辞書を添加して呼び出すときは **
funcwithnamedargs(**{'b': 10, 'a': 9})

LuanaLuana2012/07/15 14:16I read your post and wihesd I was good enough to write it

totoxdtotoxd2012/07/16 02:55f1AtSN <a href="http://lhfrbuiunogq.com/">lhfrbuiunogq</a>

jebmdnjebmdn2012/07/17 00:31ZAsYvc , [url=http://bkkdwllhepah.com/]bkkdwllhepah[/url], [link=http://ewqodtjjiwut.com/]ewqodtjjiwut[/link], http://pavbtqjhuomn.com/

ciphhnjyefjciphhnjyefj2012/07/17 12:46DncpWz <a href="http://wrugitsstzsq.com/">wrugitsstzsq</a>

kixmjlyoadkixmjlyoad2012/07/18 02:50gx6UXV , [url=http://dhjobgucinkn.com/]dhjobgucinkn[/url], [link=http://wnojehgqyufu.com/]wnojehgqyufu[/link], http://mbgttgdmsrbe.com/