質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.49%

  • Python 3.x

    6831questions

    Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

python ngramについて

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 173

rysy_9

score 11

 前提・実現したいこと

前提としてネット上に落ちていたプログラムを参考に、Python2系だったものを3系に直すことと、importの部分の追加を行いました。
目標としてweb上の文章をngram(1-10くらい)にて処理し、どのような単語が多く出ているのかを調べていくプログラムを作りたいと思っています。ただし取得するURLはjsonファイルとして保存しております。それも以下に載せます。

 発生している問題・エラーメッセージ

__getNavigableStringsの部分がよく理解できずこのようなエラーが出てしまっているのでどうか解決策、説明をいただければと思っている所存でございます。

Traceback (most recent call last):
  File "ngram.py", line 75, in <module>
    text = hp.get(url)
  File "ngram.py", line 49, in get
    text = '\n'.join(self.__getNavigableStrings(soup))
  File "ngram.py", line 58, in __getNavigableStrings
    for g in self.__getNavigableStrings(c):
  File "ngram.py", line 54, in __getNavigableStrings
    if type(soup) not in (Comment, Declaration) and soup.strip():
NameError: name 'Comment' is not defined

なおデバックのプログラムを組み、__getNavigableStringsの関数の部分がおかしいことはわかっております。Comment,Declarationなどどのように定義するといいのかを教えていただきたいです。

 該当のソースコード

# coding: utf-8

import sys
import json
import MeCab
import urllib.request, urllib.error, urllib.parse
from collections import defaultdict
from operator import itemgetter
from bs4 import BeautifulSoup
from bs4 import NavigableString


class Ngram():

    def __init__(self, N=3):
        self.N = N
        self.tagger = MeCab.Tagger("-Owakati")

    def get(self, text, ngram=None):
        seq = self.tagger.parse(text).split()

        if ngram is None:
            ngram = [defaultdict(int) for x in range((self.N + 1))]
            ngram[0] = None

        for i in range(len(seq)):
            for n in range(1, self.N + 1):
                idx = i - n + 1  # check ngram is valid range
                if idx >= 0:
                    key_words = []
                    for j in range(idx, i+1):
                        key_words.append(seq[j])
                    key = '_'.join(key_words)
                    ngram[n][key] += 1

        return ngram


class HTMLParser():

    def get(self, url):
        try:
            c = urllib.request.urlopen(url)
        except:
            print("Could not open %s" % url)
            return ""

        soup = BeautifulSoup(c.read(), "lxml")
        text = '\n'.join(self.__getNavigableStrings(soup))
        return text

    def __getNavigableStrings(self, soup):
        if isinstance(soup, NavigableString):
            if type(soup) not in (Comment, Declaration) and soup.strip():
                yield soup
        elif soup.name not in ('script', 'style'):
            for c in soup.contents:
                for g in self.__getNavigableStrings(c):
                    yield g


if __name__ == "__main__":

    f = open("urls.json", "r")
    urls = json.load(f)
    f.close()
    print("Count of urls : " + str(len(urls)))

    N = 10
    hp = HTMLParser()
    ng = Ngram(N)

    ngram = None
    for url in urls:
        text = hp.get(url)
        ngram = ng.get(text, ngram)

    for n in range(1, (N + 1)):
        f = open('outputs/{:02d}.tsv'.format(n), 'w')
        out = ""
        for k, v in sorted(list(ngram[n].items()), key=itemgetter(1), reverse=True):
            out += "{}\t{}\n".format(k, v)
        f.write(out)
        f.close()
["https://headlines.yahoo.co.jp/article?a=20180529-00000053-sasahi-life", "https://headlines.yahoo.co.jp/hl?a=20180601-00000031-asahi-soci", "https://headlines.yahoo.co.jp/hl?a=20180601-00010001-biz_shoko-bus_all", "https://news.yahoo.co.jp/byline/fuwaraizo/20180531-00085864/", "https://headlines.yahoo.co.jp/videonews/nnn?a=20180601-00000032-nnn-soci", "https://headlines.yahoo.co.jp/hl?a=20180601-00010002-reutv-bus_all", "https://headlines.yahoo.co.jp/videonews/", "https://news.yahoo.co.jp/profile/login", "https://www.yahoo-help.jp/app/answers/detail/p/575/a_id/60137", "https://news.yahoo.co.jp/pickup/6284651", "https://about.yahoo.co.jp/docs/info/terms/chapter1.html", "https://news.yahoo.co.jp/hl?c=c_life", "https://headlines.yahoo.co.jp/hl?a=20180601-00000051-asahi-spo", "https://news.yahoo.co.jp/byline/oshimakazuto/20180531-00085867/", "https://news.yahoo.co.jp/pickup/6284647", "https://www.yahoo-help.jp/app/answers/detail/a_id/43880/p/533/", "https://headlines.yahoo.co.jp/docs/copyright.html", "https://news.yahoo.co.jp/ranking", "https://headlines.yahoo.co.jp/docs/tokuteisho.html", "https://headlines.yahoo.co.jp/purchase/", "https://news.yahoo.co.jp/photo", "https://headlines.yahoo.co.jp/hl?a=20180601-00000548-san-hlth", "https://news.yahoo.co.jp/hl?c=c_sci", "https://headlines.yahoo.co.jp/hl?a=20180601-00226362-nksports-spo", "https://news.yahoo.co.jp/pickup/6284656", "https://news.yahoo.co.jp/feature", "https://about.yahoo.co.jp/info/msiesp/", "https://headlines.yahoo.co.jp/article?a=20180601-00223078-toyo-soci", "https://about.yahoo.co.jp/docs/info/terms/", "https://news.yahoo.co.jp/ranking/access?ty=v", "https://headlines.yahoo.co.jp/hl?a=20180601-00000108-spnannex-socc", "https://headlines.yahoo.co.jp/hl?a=20180601-00000519-san-pol", "https://news.yahoo.co.jp/hl?c=c_spo", "https://headlines.yahoo.co.jp/hl?a=20180601-00010003-storyfulv-s_ame", "https://news.yahoo.co.jp/flash", "https://news.yahoo.co.jp/hl?c=dom", "https://headlines.yahoo.co.jp/hl?a=20180601-00029764-mbcnewsv-l46", "https://news.yahoo.co.jp/ranking/access?ty=t", "https://news.yahoo.co.jp/hl?c=c_ent", "https://www.yahoo-help.jp/app/noscript", "https://headlines.yahoo.co.jp/hl?a=20180601-00010002-fnnprimev-soci", "https://headlines.yahoo.co.jp/videonews/jnn?a=20180601-00000029-jnn-soci", "https://news.yahoo.co.jp/pickup/6284633", "https://news.yahoo.co.jp/hl?c=loc", "http://news.yahoo.co.jp/", "https://news.yahoo.co.jp/byline/kohyoungki/20180531-00085870/", "https://news.yahoo.co.jp/pickup/6284642", "https://news.yahoo.co.jp/profile/settings/", "https://news.yahoo.co.jp/polls/", "https://about.yahoo.co.jp/info/mediastatement/", "https://news.yahoo.co.jp/pickup/6284641", "https://headlines.yahoo.co.jp/article?a=20180601-00000021-sasahi-soci", "https://news.yahoo.co.jp/byline/", "https://news.yahoo.co.jp/pickup/6284638", "https://news.yahoo.co.jp/hl?c=c_int", "https://headlines.yahoo.co.jp/videonews/ann?a=20180601-00000005-ann-soci", "https://news.yahoo.co.jp/list/", "https://news.yahoo.co.jp/zasshi", "https://news.yahoo.co.jp/hl?c=bus", "https://news.yahoo.co.jp/ranking/comment/rate?ty=t", "https://news.yahoo.co.jp/ranking/access?ty=z", "https://news.yahoo.co.jp/ranking/access?ty=b", "https://news.yahoo.co.jp/", "https://feedback.ms.yahoo.co.jp/voc/news-voc/input", "https://news.yahoo.co.jp/pickup/6284649", "https://news.yahoo.co.jp/search/advanced", "https://www.yahoo-help.jp/app/home/p/575/", "https://news.yahoo.co.jp/topics"]

 参考文献

巨人の肩の上に登る
http://mayo.hatenablog.com/entry/2013/12/09/012939

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • hayataka2049

    2018/06/01 19:41 編集

    出典(参考にしたページ)を明記してくれませんか

    キャンセル

  • rysy_9

    2018/06/01 19:44

    追加させていただきました

    キャンセル

回答 1

checkベストアンサー

+1

beautifulsoupの使い方はまったく知りませんが、とりあえずimportすればそのエラーは消えませんか?

こんな感じで。

from bs4 import Comment, Declaration

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.49%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • Python 3.x

    6831questions

    Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。