11325


クローラーを作ろうと思い、webページのリンクを抽出するコードを欠いていたのですが、  
以下の部分で "Attribute Error 'tuple' object hano attribute
find"というエラーが出てしまいます。どうすれば回避できるでしょうか  
補足：御助言ありがとうございます。コード全体はこのようになってます。

[code]

    def get_page(page):
        start_link = page.find("<a href=")
        if start_link == -1:
            return None, 0
        start_quote = page.find('"', start_link)
        end_quote = page.find('"', start_quote+1)
        url =  page[start_quote+1 : end_quote]
        return url, end_quote
    
    
    def all_get_links(page):
        while True:
            url, end_quote = get_page(page)
            if url:
                print(url)
                page = page[end_quote:]
            else:
                break
    
    
    print(all_get_links(get_page("http://www.yahoo.co.jp/")))
    
[/code]


CC BY-SA 3.0
2015-06-14T06:40:14.190
11324
2015-06-15T15:04:36.753
2015-06-15T15:04:36.753
2901
9597
question
python
pythonでのwebページのリンク抽出について


get_pageがtupleを返しているからではないでしょうか?  
`get_page`は`(url, end_quote)`のtupleを返しています。  
最後の行でget_pageが返したtupleを引数にall_get_linksを呼んでいますが、そうなるとall_get_linksの引数のpageはtupleになってしまい、tupleにfindメソッドがないのでこのようなエラーが出ています。

このエラーは`tupleにはfindという属性がありません`という意味です。

追記: 最後の行のget_pageの引数が`http://www.yahoo.co.jp/`なのでpage.findは`<a href=`という文字列を
**見つけられません** 。(`http://www.yahoo.co.jp/`の中に`<a href=`という文字列は含まれていない)
そのため返ってくるtupleは必ず`(None, 0)`になってしまいます。これを回避するためにはget_pageに渡す文字列には、きちんとした a tag
が含まれるようにしてください。

追記2:  
下記のような感じにするのはいかがでしょうか?

[code]

    
    def get_page(page):
        start_link = page.find("<a href=")
        if start_link == -1:
            return None
        start_quote = page.find('"', start_link)
        end_quote = page.find('"', start_quote+1)
        url =  page[start_quote+1 : end_quote]
        print(url)
        return page[end_quote:]
    
    def all_get_links(page):
       while True:
            page = get_page(page)
            if page == None:
                break
    
    page = '<a href="http://rebuild.fm">Rebuild.fm</a>'
    all_get_links(page) # http://rebuild.fm と表示される
    
    
[/code]

このやり方だとget_pageは文字列かNoneを返すようになります。Noneを返した場合、すぐにbreakして、whileから抜けるのでエラーにはなりません。Noneではない場合は必ず文字列を返すので、最初のようなエラーは起こりません。

他のやり方として、html.parserのHTMLParserクラスを継承して使うのがいいと思います。  
例としては下記のような感じでしょうか

[20.2. html.parser— HTML および XHTML のシンプルなパーサー — Python 3.4.3
ドキュメント](http://docs.python.jp/3/library/html.parser.html)

[code]

    
    from html.parser import HTMLParser
    
    class MyParser(HTMLParser):
        def handle_starttag(self, tag, attrs):
            attrs_dict = dict(attrs)
            if tag == "a":
                print(attrs_dict["href"]) #hrefの内容を表示
    
    
    
[/code]


CC BY-SA 3.0
2015-06-14T06:56:01.177
11325
2015-06-15T14:30:16.663
2015-06-15T14:30:16.663
5246
5246
11324
answer


最近、あまり使っていないのですが、昔、HTMLパーシングには、[BeautifulSoup](http://www.crummy.com/software/BeautifulSoup/bs4/doc/)をよく使っていました。

[code]

    from bs4 import BeautifulSoup
    
    soup = BeautifulSoup(html_data)
    links = []
    for link in soup.find_all("a"):
        if hasattr(link, "href"):
            links.append(link.attrs.get("href"))
    
[/code]


CC BY-SA 3.0
2015-06-15T05:05:10.493
11362
2015-06-15T05:05:10.493
2314
11324
answer