49396


スクレイピングで以下のコードを動かしたいのですが、以下のエラーが出てしまいます。  
もしよろしければ、ご教授お願いいたします。

**実行時のエラーメッセージ**

[code]

    fetching data... http://www.haiku-data.jp/work_detail.php?cd=9 result: SUCCESS
    Traceback (most recent call last):
    File "/home/yudai/Desktop/haiku_correct.py", line 52, in <module>
    for fname, word in zip(poem, morphes):
    NameError: name 'poem' is not defined
    
[/code]

**ソースコード**

[code]

    # -*- coding: utf-8 -*-
    import time
    from urllib import request
    from bs4 import BeautifulSoup
    import MeCab
    import codecs
    import re
    
    def get_data(url):
        req = request.urlopen(url)
        soup = BeautifulSoup(req.read(), 'html.parser')
    
        # 俳句
        poem_elem = soup.select('td[height=40] b')[0]
        poem = poem_elem.text.replace('*', '').strip()  # サニタイズ
        if not poem:
            return False  # 存在しないID
    
        return {'poem': poem}
    
    morphes = []
    MAX_ID = 10  # 登録されているIDの最大値
    for i in range(1, MAX_ID):
        url = 'http://www.haiku-data.jp/work_detail.php?cd={id}'.format(id=i)
        print('fetching data... ' + url, end=' ')
        d = get_data(url)
        if d:
            print('result: SUCCESS')
            morphes.append(d)
        else:
            print('result: MISSING')
    
        time.sleep(1)  # アクセス間隔
    
    def write2file(fname, sentences):
        with codecs.open(fname, 'w', 'utf-8') as f:
            f.write("".join(f, fieldnames=['poem']))
    
    def get_morphemes(sentences):
        morphemes = []
        for sent in sentences:
            if len(sent) == 0:
                continue
            temp = tagger.parse(sent).split()
            temp.append("。\n")
            morphemes.append(" ".join(temp))
        return morphemes if morphemes else -1
    
    tagger = MeCab.Tagger("-Owakati")
    
    for fname, word in zip(poem, morphes):
        with req.urlopen(link + par.quote_plus(word)) as response:
            html = response.read().decode('utf-8')
            morphes = []
            for p in all_p_tag:
                # 半角文字を削除
                p = re.sub("[\s!-~]*", "", p)
                p = p.split("。")
                # 分かち書き
                morphemes = get_morphemes(p)
                if morphemes == -1:
                    continue
                temp = temp + morphemes
            write2file(fname + ".txt", temp)
    
[/code]


CC BY-SA 4.0
2018-10-17T13:03:22.387
49386
2020-04-06T06:25:45.847
2020-04-06T06:25:45.847
3060
30516
question
python python3 web-scraping mecab
スクレイピングでmecabが動きません


今回のエラーは、一番最後の for 文の部分で起こっています。

[code]

    for fname, word in zip(poem, morphes):
    
[/code]

この行において「`poem` という変数が見つからないよ」というのがエラーの内容です。

今回のプログラムにおいて `poem` という変数は `get_data`
関数の中で出てきていますが、これは関数のスコープ内部で宣言されたローカル変数であるため関数の外で使うことはできません。ここ以外の他のどこにも `poem`
という変数は無いので「見つからないよ」というエラーが出ているわけです。

解決策ですが、今回 `get_data` 関数は返り値として `poem` の内容を渡しており、しかも変数 `d` および `morphes`
にその返り値を保存してあります。というわけでもし `get_data` 関数内に登場した `poem` の中身を使いたいなら `morphes`
を使えばよいです。ところがそうなると、元々の for 文の `zip(poem, morphes)`
という書き方はおかしいです。何か誤解なさっている可能性が高いです。更にその `for` 文の中で同名の `morphes`
という変数が使われているので更にややこしくなっています。

おそらくスクレイピングしてきた各俳句に対して何かしらのファイル名をつけたかったのだと思うので、適切なファイル名を指定する形に書き換える必要があるでしょう。


CC BY-SA 4.0
2018-10-17T15:09:54.300
49393
2018-10-17T15:09:54.300
19110
49386
answer


今回のエラーは、`for fname, word in zip(poem,
morphes):`において、`poem`という変数が見つからないというのが原因です。しかしながら、コードをみると、`poem`以外にも「変数が見つからないという」エラーになるものが数個あります。それで、処理を簡素化して取り敢えず動くコードにしてみました。

[code]

    import time
    from urllib import request
    from bs4 import BeautifulSoup
    import MeCab
    
    
    def get_data(url):
        req = request.urlopen(url)
        soup = BeautifulSoup(req.read(), 'html.parser')
    
        # 俳句
        poem_elem = soup.select('td[height=40] b')[0]
        poem = poem_elem.text.replace('*', '').strip()  # サニタイズ
        if not poem:
            return False  # 存在しないID
        return {'poem': poem}
    
    
    def write2file(i, morphemes):
        with open('poen.txt', 'a', encoding="utf-8") as f:
            f.write(str(i) + ' ' + morphemes + '\n')
    
    
    def get_morphemes(sentences):
        temp = tagger.parse(sentences).split()
        return " ".join(temp)
    
    
    tagger = MeCab.Tagger("-Owakati")
    MAX_ID = 10  # 登録されているIDの最大値
    for i in range(1, MAX_ID):
        url = 'http://www.haiku-data.jp/work_detail.php?cd={id}'.format(id=i)
        print('fetching data... ' + url, end=' ')
        d = get_data(url)
        if d:
            print('result: SUCCESS')
            morphemes = get_morphemes(d['poem'])
            write2file(i, morphemes)
        else:
            print('result: MISSING')
    
        time.sleep(1)  # アクセス間隔
    
[/code]

多分、希望するコードにはなっていないと思いますが、その場合にはどうしたいかを質問に追記してください。


CC BY-SA 4.0
2018-10-17T23:15:33.583
49396
2018-10-17T23:15:33.583
15171
49386
answer