2013年3月24日日曜日

PythonでWebページを取得しURLの抽出する

利用ツール&モジュール
- Python2.6以上
- HTMLParser
- urllib2,urllib

試しに当ブログのトップページに含まれるリンクを抽出するスクリプトを作成しました。



# -*- coding: utf-8 -*-

# http://ymotongpoo.hatenablog.com/entry/20081211/1228985067
# http://nihitok.blogspot.jp/2011/07/pythonhtml.html

# Modules ------------------------
from HTMLParser import HTMLParser
import urllib, urllib2
import fnmatch

# Classes ------------------------
class My_parser(HTMLParser):
    
    # My_parserインスタンスが生成された際に呼び出されるコンストラクタ 
    def __init__(self):
        HTMLParser.__init__(self)
        self.is_data = False
        self.href    = None
        self.val     = None
        self.data    = []
    
    # 開始タグにぶつかったらhandle_starttag()を呼ぶ
    def handle_starttag(self,tagname,attribute):
        if tagname.lower() == "a":
            for i in attribute:
             if i[0].lower() == "href" and fnmatch.fnmatch(i[1], "http*"):
              self.is_data = True
              self.href    = i[1]

    # 終了タグにぶつかったらhandle_endtag()を呼ぶ                
    def handle_endtag(self,tag):
        if tag.lower() == "a":
            self.is_data = False
            self.data.append({
                "url":self.href,
                "val":self.val
                })
            self.href = None
            self.val = None

    # タグで挟まれてる中身はhandle_data()で処理
    def handle_data(self,data):
     if self.is_data:
      self.val = data

# Function -----------------------------
def main(html):
    parser = My_parser()
    parser.feed(html)
    return parser.data


# Parameters ----------------------------

# Proxy経由でアクセス
proxy_support = urllib2.ProxyHandler({'http': '195.140.190.146:8080'})
opener        = urllib2.build_opener(proxy_support)
urllib2.install_opener(opener)


url = 'http://shiroibanana.blogspot.jp/'
r   = urllib2.urlopen(url) # get webpage

headers    = r.info()    # ヘッダ情報を取得
data       = r.read()    # HTMLファイルの取得
parsedData = main(data)  # パース

# 表示
for i in range(0, len(parsedData)):
    t = parsedData[i]
    if t["url"] != None:
     print t["url"], t["val"]

f = open("out.html", "w")
f.write(data)
f.close()





実行結果はこんな感じで、URLとリンクされてる文字列のペアを抽出してます。



$ python spider.py
http://shiroibanana.blogspot.jp/2013/03/blog-post_23.html 家電芸人で紹介された最高な家電まとめ
http://www.raycop.jp/products/smart.html raycop のSMART
http://www.raycop.jp/products/img/p_smart_white.jpg None
http://www.sharp.co.jp/cocorobo/ COCOROBO
http://www.sharp.co.jp/cocorobo/cms/images/btn_lineup_v80.jpg None
http://www.sony.jp/handycam/products/HDR-PJ790V/ SONY HDR PJ-790v
http://www.sony.jp/products/picture/large/hdr-pj790v_open.jpg None
http://www.popphoto.com/gear/2012/10/new-gear-gopro-hero3-black-edition-captures-4k-video GoPro HERO3
http://www.popphoto.com/files/imagecache/article_main_photo/_images/201210/c10.18goproevent01.jpg None
http://netafull.net/ipad-app/042900.html DynaMapper
http://www.blogger.com/post-edit.g?blogID=4715403609105568520&postID=3622915893062832885&from=pencil

http://shiroibanana.blogspot.jp/2013/03/recruit-card.html これからはRecruit Card?
http://markezine.jp/article/detail/17450 を展開
http://www.blogger.com/post-edit.g?blogID=4715403609105568520&postID=1195829771076099757&from=pencil

http://shiroibanana.blogspot.jp/2013/03/1python.html 1分でPythonでスクレイピングツールを作る
http://www.gesource.jp/programming/python/code/0013.html sqlite3
http://www.kdl.co.jp/open/2011/04/21/python/ pythonでスクレイピングツールつくろうぜ
http://www.blogger.com/post-edit.g?blogID=4715403609105568520&postID=1367463051003792010&from=pencil

http://shiroibanana.blogspot.jp/2013/03/blog-post_6.html つけまつげ
http://www.blogger.com/post-edit.g?blogID=4715403609105568520&postID=8999922777856394962&from=pencil

http://shiroibanana.blogspot.jp/2013/03/sdk.html SDK開発者として
http://www.blogger.com/post-edit.g?blogID=4715403609105568520&postID=7481504868617649295&from=pencil

http://shiroibanana.blogspot.jp/2013/03/blog-post.html アメリカ出張
http://www.blogger.com/post-edit.g?blogID=4715403609105568520&postID=9018148613665132091&from=pencil

http://shiroibanana.blogspot.jp/2013/02/blog-post.html ライブラリの設計思想
http://www.blogger.com/post-edit.g?blogID=4715403609105568520&postID=3141501431117496890&from=pencil

http://shiroibanana.blogspot.jp/search?updated-max=2013-02-19T00:24:00%2B09:00&max-results=7 前の投稿
http://shiroibanana.blogspot.jp/ ホーム
http://shiroibanana.blogspot.com/feeds/posts/default 投稿 (Atom)
http://shiroibanana.blogspot.jp/2012/10/nexus7_4.html

http://shiroibanana.blogspot.jp/2012/10/nexus7_4.html 俺はなる
http://shiroibanana.blogspot.jp/2012/05/blog-post.html 構文エラー : ';' が '型' の前にありません
http://shiroibanana.blogspot.jp/2012/02/c.html

http://shiroibanana.blogspot.jp/2012/02/c.html C++プログラミング入門(1) // 倉庫番プログラムの実装
http://shiroibanana.blogspot.jp/2012/05/blog-post_13.html 内向的で無口な人向けの会話術
http://shiroibanana.blogspot.jp/2012/01/dvd.html の技術 (DVDまとめ)
http://shiroibanana.blogspot.jp/2012/06/python.html Pythonによるソーシャルデータ分析入門
http://shiroibanana.blogspot.jp/2012/01/ivs-2011.html IVS 2011
http://shiroibanana.blogspot.jp/2012/09/callback.html Callback関数を知らん人がまず理解すべきことのまとめ
http://shiroibanana.blogspot.jp/2012/02/blog-post.html 集合知プログラミング
http://shiroibanana.blogspot.jp/2012/03/google-app-engine-for-java-1.html Google App Engine for Java (1)
http://shiroibanana.blogspot.jp/search/label/C%2B%2B C++
http://shiroibanana.blogspot.jp/search/label/Web Web
http://shiroibanana.blogspot.jp/search/label/%E6%9B%B8%E7%B1%8D 書籍
http://shiroibanana.blogspot.jp/search/label/DVD DVD
http://shiroibanana.blogspot.jp/search/label/%E3%82%A8%E3%83%B3%E3%82%BF%E3%83%A1 エンタメ
http://shiroibanana.blogspot.jp/search/label/%E6%9C%AC 本
http://shiroibanana.blogspot.jp/search/label/%E8%AC%9B%E6%BC%94 講演
http://shiroibanana.blogspot.jp/search/label/%E9%80%9A%E4%BF%A1 通信
http://www.blogger.com/profile/04178558922499888726
shiroibanana

http://www.blogger.com/profile/04178558922499888726 詳細プロフィールを表示
http://shiroibanana.blogspot.jp/search?updated-min=2013-01-01T00:00:00%2B09:00&updated-max=2014-01-01T00:00:00%2B09:00&max-results=10 2013
http://shiroibanana.blogspot.jp/2013_03_01_archive.html 3月
http://shiroibanana.blogspot.jp/2013/03/blog-post_23.html 家電芸人で紹介された最高な家電まとめ
http://shiroibanana.blogspot.jp/2013/03/recruit-card.html これからはRecruit Card?
http://shiroibanana.blogspot.jp/2013/03/1python.html 1分でPythonでスクレイピングツールを作る
http://shiroibanana.blogspot.jp/2013/03/blog-post_6.html つけまつげ
http://shiroibanana.blogspot.jp/2013/03/sdk.html SDK開発者として
http://shiroibanana.blogspot.jp/2013/03/blog-post.html アメリカ出張
http://shiroibanana.blogspot.jp/2013_02_01_archive.html 2月
http://shiroibanana.blogspot.jp/2013_01_01_archive.html 1月
http://shiroibanana.blogspot.jp/search?updated-min=2012-01-01T00:00:00%2B09:00&updated-max=2013-01-01T00:00:00%2B09:00&max-results=44 2012
http://shiroibanana.blogspot.jp/2012_10_01_archive.html 10月
http://shiroibanana.blogspot.jp/2012_09_01_archive.html 9月
http://shiroibanana.blogspot.jp/2012_08_01_archive.html 8月
http://shiroibanana.blogspot.jp/2012_07_01_archive.html 7月
http://shiroibanana.blogspot.jp/2012_06_01_archive.html 6月
http://shiroibanana.blogspot.jp/2012_05_01_archive.html 5月
http://shiroibanana.blogspot.jp/2012_04_01_archive.html 4月
http://shiroibanana.blogspot.jp/2012_03_01_archive.html 3月
http://shiroibanana.blogspot.jp/2012_02_01_archive.html 2月
http://shiroibanana.blogspot.jp/2012_01_01_archive.html 1月
http://www.blogger.com Blogger