BeautifulSoup を諦め HTMLParser使ってみた。
結局、シンプルなHTMLParserを使って作ってみた。id:aodag先生に大変お世話になりました。とりあえづ、昨晩やったこと。HTMLParserで、やってみた。
標準のhandle_dataを変更して、scriptタグとstyleタグとコメントを無視するようにしたTagStripクラスを作る。
# condig:utf-8 from HTMLParser import HTMLParser class TagStrip(HTMLParser): def __init__(self): HTMLParser.__init__(self) self.datum = [] self.instyle = False def handle_data(self, data): if data.strip() and not self.instyle: self.datum.append(data) def getString(self): return "".join(self.datum) def handle_starttag(self, tag, attrs): if tag == 'style' or tag == 'script': self.instyle = True def handle_endtag(self, tag): if tag == 'style' or tag == 'script': self.instyle = False if __name__ == '__main__': html = ''' <html><head> <script> this is script </script> </head> <body> <p>P string</p> <div>Div string</div> <br> <table><tr> <td>TD string</td> </tr></table> </body> </html> ''' p = TagStrip() p.feed(html) print p.getString()
このままhtml食わせたら、問題ないかと思ったら、
<'scr' + 'ipt'>
とかで、パースでこける。あと、文字コードをcontent-typeから決定しようと思ったけど、content-typeの設定されていないページが平気であったりする。これらのを回避する為に、htmlをゲットするときにcharsetを自動判定して、適当に整理するメソッドを作った。
def getHtml(url): response = urlopen(url).read() response = response.replace("</scr' + 'ipt>", "</script>") response = response.replace("<scr' + 'ipt", "<script") enc = chardet.detect(response) if enc['encoding'].lower() == 'shift_jis': return response.decode('shift-jis') elif enc['encoding'].lower() == 'euc-jp': return unicode(response, 'euc-jp', 'ignore') elif enc['encoding'].lower() == 'iso-2022-jp': return response.decode('iso-2022-jp') else: return response
あとは、ひたすらはてブから、linkを引っ張ってきてグルグル回す
# coding:utf-8 from urllib import urlopen from BeautifulSoup import BeautifulSoup from splitter import split from pit import Pit from pyhatebu import PyHatebu from htmlStrip import TagStrip import re import chardet # encoding matchCharset = re.compile(r'charset=(?P<charset>[\w-]+)') uid = Pit.get('hatena.ne.jp') h = PyHatebu(uid['login'], uid['password']) if __name__ == '__main__': for i in h.feed(): print '-' * 80 print i.title print i.link str = getHtml(i.link) a = TagStrip() a.feed(str) res = a.getString() res = getContent(i.link) print res['enc']
今朝見てみたら、id:y_yanbeさんが素敵なコードをくれたので後で試してみる。