2009年12月1日星期二

如何parse需要帳號密碼登入的網頁 -- use twill library

這陣子要 parse citeulike 網頁上的一些資訊來當作實驗的數據
說到寫 parser,第一個想到的工具當然是 python。
Google 了一下,發現一個比 BeautifulSoup 效能更好的 library: lxml
lxml 同樣支援 xpath,所以 parse xml 或 html 很方便。

但真的動手後發現一個問題:citeulike 上很多資訊得 login 之後才能看得到。
該怎麼用 python 完成 "login" 的動作以得到這些資訊呢? :-(

Google 了一整天,終於發現一個還不錯的工具。
twill: a simple scripting language for Web browsing
http://twill.idyll.org/

twill 可以幫助我們完成網頁中 "填表單" 的動作
而且,可以從 python 中直接使用 twill。
所以,如果要 parse 的網頁需要登入時,我們可以用 twill + lxml 來完成工作。 :-)

附上最後完成的程式供未來參考,此程式的目的是要 parse citeulike 網站上某特定使用者的 connection (friend) list。parseConnections 這個 function 寫得有點髒,不過堪用就是了。

from twill.commands import go, formclear, fv, submit, show
import StringIO
import twill
import cStringIO
import sys
from lxml import etree

def parseConnections(html):
contact = []
parser = etree.HTMLParser(encoding='utf8')
tree = etree.parse(cStringIO.StringIO(html), parser)
links = tree.xpath('//a/text()');
for i in range(51,len(links)): # the 51st link is the first contact (friend)
if (links[i] not in contact):
contact.append(links[i])
print links[i]
else:
break

twill.set_output(StringIO.StringIO()) # surpress twill screen output

url = 'http://www.citeulike.org/connections/elsantosneto'
go(url)

# login to the website
formclear('2')
fv('2', 'username', sys.argv[1])
fv('2', 'password', sys.argv[2])
submit('0')

# parse the html
html = show()
parseConnections(html)

print('\n\nfinish parsing')

0 意見: