おまけ
に貼ったリスト作るのに使った Python スクリプト。(Python 2.5 用)
使い方
から取得した HTML を適当な名前でセーブして、
# tableget.py # HTML の table を TSV(TAB 区切り表形式データ)に # UTF-8 専用 '''HTML table to TSV.''' __version__ = '1.0.0' __date__ = '2007-07-14' __author__ = 'kadotanimitsuru' from HTMLParser import HTMLParser, HTMLParseError from htmlentitydefs import name2codepoint class Parser(HTMLParser): def __init__(self, anchor=True): HTMLParser.__init__(self) self.tables = [] self.nest = 0 self.sel = False self.data = None self.anchor = anchor def _data_store(self): if self.data is not None: data = ' '.join(''.join(self.data).strip().split()) self.tables[-1][-1].append(data) self.data = None def handle_starttag(self, tag, attrs): if tag == 'table': if self.nest: raise HTMLParseError('table nested', self.getpos()) self.nest += 1 self.tables.append([]) elif tag == 'tr': self.tables[-1].append([]) elif tag in ('th', 'td'): self.data = [] self.sel = True elif self.sel: if self.anchor and tag == 'a': self.data.append(' [%s ' % (dict(attrs).get('href', ''),)) elif tag == 'img': self.handle_data(dict(attrs).get('alt', '')) def handle_endtag(self, tag): if tag == 'table': if not self.nest: raise HTMLParser.HTMLParseError( self, 'table nested.', self.getpos()) self.nest -= 1 elif tag == 'tr': self.sel = False elif tag in ('th', 'td'): self._data_store() self.sel = False elif self.sel: if self.anchor and tag == 'a': self.data.append('] ') def handle_data(self, data): if self.sel: self.data.append(data) def handle_charref(self, ref): if ref[0] in ('x', 'X'): i = int(ref[1:], 16) else: i = int(ref) self.handle_data(unichr(i)) def handle_entityref(self, name): c = name2codepoint.get(name, '&%s;' % (name,)) if isinstance(c, int): c = unichr(c) self.handle_data(c) def get_tsv(self): tables = [] for t in self.tables: tsv = [] for line in t: tsv.append('\t'.join(line)) tables.append('\n'.join(tsv)) return tables def tableget(html, anchor=True): '''List of TSV is returned. Arguments: html: Sauce HTML (Unicode or Ascii) anchor: Does it leave a text a link? ''' p = Parser(anchor) p.feed(html) p.close() return p.get_tsv() usage = u'''ローカルに置いた HTML ファイルを指定してください。 HTML ファイルはあらかじめ UTF-8 にしておく必要があります。 HTML ファイル中の table はネストしてはいけません。 colspan, rowspan にも対応していません。 'table?.txt' という形式で表計算ソフト等で扱える TAB 区切りの表が出来ます。 ''' if __name__ == '__main__': print usage, filename = raw_input('HTML filename:') html = open(filename, 'U').read() try: html = unicode(html, 'utf') except UnicodeDecodeError: html = unicode(html) tables = tableget(html) for i, t in enumerate(tables): filename = 'table%d.txt' % (i,) print filename f = open(filename, 'w') f.write(t.encode('utf')) f.close() # Public domain. 好きに流用してください
でタブ区切りテキスト(table0.txt)に変換。
そこから手動で読んだ作品の行だけ抜き出して read.txt というファイル名でセーブ。そして、
import os.path HTML5 = '''<!doctype html> <html> <head> <meta charset="UTF-8"> <title>%s</title> </head> <body> %s </body> </html>''' def tsv2table(tsv): table = [] for l in tsv.strip().splitlines(): table.append(l.split('\t')) return table def table2tsv(table): return '\n'.join(['\t'.join(x) for x in table]) def tohtml(table): a = [] for ( title, author, illustrator, label, edition, price, date, comment, link, vote) in table: ref = link.split('] [')[-1].split()[0] a.append( u'<li>%(title)s <small>(著者:%(author)s, イラスト:%(illustrator)s) <a href="%(ref)s">%(label)s</a></small></li>' % locals()) return u'''<ol> %s </ol> ''' % '\n'.join(a) def tablesort(filename): tsv = open(filename, 'U').read() try: tsv = unicode(tsv, 'utf') except UnicodeDecodeError: tsv = unicode(tsv) table = tsv2table(tsv) table.sort(cmp=lambda x,y: cmp( (x[1], x[3], [int(i) for i in x[6].split('/')], x[0]), (y[1], y[3], [int(i) for i in y[6].split('/')], y[0]))) tsv = table2tsv(table) root, ext = os.path.splitext(filename) tsvfile = root + '_sorted' + ext htmlfile = root + '.htm' print tsvfile, htmlfile f = open(tsvfile, 'w') f.write(tsv.encode('utf')) f.close() f = open(htmlfile, 'w') f.write((HTML5 % (filename, tohtml(table))).encode('utf')) f.close() if __name__ == '__main__': filename = raw_input('tsv filename:') tablesort(filename) # Public domain. 好きに流用してください
を実行。すると read_sorted.txt と read.htm という2つのファイルが出来上がります。read.htm の方がそれなので、あとはその中の ol要素 を blog なりに貼りつければ OK。(先のリストはこの出力に更に手動で手を加えてシリーズをまとめて2段リストにしたり未読を斜体にしたりしています)