예제 #1
0
  def _create_table(self, reviews: Tuple[ReviewInfo, ...]) -> str:
    """レビュー情報一覧から table 要素を作成する

    Args:
      reviews (Tuple[ReviewInfo, ...]): レビュー情報一覧

    Returns:
      table タグで囲まれたテキスト
    """
    thead = tag('thead', tag('tr', tag('th', *ReviewInfo._fields)))
    tr_content_list = list()
    for review_info in reviews:
      # レビュー文の処理
      review = review_info.review.replace('\n', '<br>')
      review_info = review_info._replace(review=review)

      if self.normalize_mode:
        review = normalize(review)

      # 列要素を作成
      td_content_list = [tag('td', info) for info in review_info]

      # 行要素を作成
      tr = organize_contents(td_content_list, 'tr')
      tr_content_list.append(tr)

    tbody = organize_contents(tr_content_list, 'tbody')
    table_content_list = [thead, tbody]
    table = organize_contents(
        table_content_list, 'table',
        class_='tablesorter tablesorter-{}'.format(TABLE_DESIGN),
        id=OLD_AND_NEW[1]
    )
    return table
예제 #2
0
  def convert(self, map_jsonfile: Union[str, pathlib.Path]) -> str:
    """商品レビュー内の文を属性と星評価別に対応付けされた JSON ファイルを見やすいように html ファイルに変換

    Args:
      map_jsonfile (Union[str, pathlib.Path]): 対応付けの結果を格納した JSON ファイル

    Returns:
      html で記述されたテキスト
    """
    mapped_data = MappingResult.load(map_jsonfile)
    self.category = mapped_data.category

    # head コンテンツ
    product_name = mapped_data.product
    title = tag('title', product_name)
    head_content_list = [*self._head_contents, title]
    head = organize_contents(head_content_list, 'head')

    # body コンテンツ
    body = self._make_body_content(mapped_data)

    # html コンテンツ
    html_content_list = [head, body]
    html = organize_contents(html_content_list, 'html')
    html = DOC_TYPE + '\n' + html
    return html
예제 #3
0
  def _convert_review_data_to_body_content(
      self, reviewdata: ReviewPageJSON) -> str:
    """レビューデータを html の body 要素に変換する

    Args:
      reviewdata (ReviewPageJSON): Amazon レビューデータ

    Returns:
      body タグで囲まれたテキスト
    """
    real_reviews  = reviewdata.real_reviews
    num_reviews_text = 'レビュー数:{}'.format(real_reviews)
    total_reviews = reviewdata.total_reviews
    if total_reviews != real_reviews:
      num_reviews_text = '{} / {}'.format(num_reviews_text, total_reviews)

    reviews = reviewdata.reviews
    h3_content_list = _make_stars_texts(reviews, reviewdata.stars_distribution)
    # <body>コンテンツの用意
    body_content_list = [
        tag('h1', reviewdata.product),
        tag('h2', tag('a', '商品レビューページ', href=reviewdata.link)),
        tag('h2', 'メーカー:{}'.format(reviewdata.maker)),
        tag('h2', '評価:{}'.format(reviewdata.average_stars)),
        tag('h2', num_reviews_text),
        *h3_content_list,
    ]

    # <table>コンテンツの用意
    table = self._create_table(reviews)

    # <body>コンテンツの再設定
    body_content_list.append(table)
    body = organize_contents(body_content_list, 'body')
    return body
예제 #4
0
  def _create_heatmap_table(
      self, heatmap_dict: HeatmapDict, anchor_dict: AnchorDict
  ) -> str:
    """属性と星評価別にレビュー文中の文数をヒートマップにして可視化したものを table タグで作成

    Args:
      heatmap_dict (HeatmapDict): 属性と星評価別にレビュー文中の文数をまとめた辞書
      anchor_dict (AnchorDict): 属性と星評価別にレビュー文の情報をまとめたリストとアンカーを格納した辞書

    Returns:
      ヒートマップを実装した table タグ
    """
    tr_content_list = [tag('th', '属性', class_='first')]
    star_strs = tuple(STAR_DISPLAY_DICT[star_str] 
                      for star_str in STAR_CORRESPONDENCE_DICT.values())
    tr_content_list.extend([tag('th', star_str) 
                            for star_str in star_strs[:-1]])
    tr_content_list.append(tag('th', star_strs[-1], class_='last'))
    tr = organize_contents(tr_content_list, 'tr')
    thead = tag('thead', tr)

    jump_fmt = '#{}'
    tbody_content_list = []
    for attr in heatmap_dict:
      if attr != "その他":
        attr_anchor = tag('a', attr, 
                          href=jump_fmt.format(self._attr_ja2en[attr]))
        td_header = tag('td', attr_anchor, class_='stats-title')
        td_content_list = [td_header]
        num_texts_and_anchor_props = zip(heatmap_dict[attr].values(),
                                         anchor_dict[attr].values())
        for num_texts, anchor_prop in num_texts_and_anchor_props:
          anchor = tag('a', num_texts, 
                       href=jump_fmt.format(anchor_prop.link_id))
          td_content = tag('td', anchor)
          td_content_list.append(td_content)
        
        tr = organize_contents(td_content_list, 'tr', class_='stats-row')
        tbody_content_list.append(tr)

    tbody = organize_contents(tbody_content_list, 'tbody')
    table = organize_contents(
        [thead, tbody], 'table', class_='heat-map', cellpadding='0',
        cellspacing='0', border='0', id='heat-map-3')
    return table
예제 #5
0
  def _itemize_text_by_attr_and_star(
      self, attr_to_star_map: Attr2StarMap, anchor_dict: AnchorDict
  ) -> Tuple[str, ...]:
    """属性と星評価別にレビュー文中の文を列挙する

    Args:
      attr_to_star_map (Attr2StarMap): 属性と星評価別にレビュー文中の文を格納した辞書
      anchor_dict (AnchorDict): 属性と星評価別にレビュー文の情報をまとめたリストとアンカーを格納した辞書

    Returns:
      列挙された文一覧
    """
    display_fmt = '{}:{}'
    enum_content_list = list()
    for en_attr in attr_to_star_map:
      attr = self._mapper.en2ja[en_attr]
      enum_content_list.append(tag('h2', attr, id=en_attr))
      for star_str, anchor_prop in anchor_dict[attr].items():
        link_id, review_text_info_list = anchor_prop
        star_disp = STAR_DISPLAY_DICT[star_str]
        enum_content_list.append(
            tag('h3', display_fmt.format(attr, star_disp), id=link_id))
        if review_text_info_list:
          li_content_list = list()
          for review_text_info in review_text_info_list:
            text = review_text_info.text
            summary = tag('summary', text)
            review = normalize(review_text_info.review)
            marked_text = tag('span', text, class_='sentence-marker')
            marked_review = review.replace(text, marked_text)
            details_content_list = [
                summary, marked_review.replace('\n', '<br>')
            ]
            details = organize_contents(details_content_list, 'details')
            li_content_list.append(tag('li', details))

          ul = organize_contents(li_content_list, 'ul')
          enum_content_list.append(ul)

    return tuple(enum_content_list)
예제 #6
0
  def convert(self, reviewjson: Union[str, pathlib.Path]) -> str:
    """jsonファイルを読み込み、htmlフォーマットに変換

    Args:
      reviewjson (Union[str, pathlib.Path]): jsonファイルのパス

    Returns:
      JSON ファイルの中身を html に変換したもの(BeautifulSoup による整形済み)
    """
    reviewdata = ReviewPageJSON.load(reviewjson)
    head = self._make_head_content(reviewdata.product)
    body = self._convert_review_data_to_body_content(reviewdata)
    html = organize_contents((head, body), 'html')
    html = DOC_TYPE + '\n' + html

    # BeautifulSoupで整形
    bs = BeautifulSoup(html, 'lxml')
    return bs.prettify()
예제 #7
0
  def _make_body_content(self, mapped_data: MappingResult) -> str:
    """html の body タグを作成

    Args:
      mapped_data (MappingResult): 対応付けされた結果

    Returns:
      body タグ
    """
    body_content_list = []
    # h1コンテンツ
    h1_content = tag('h1', mapped_data.product)
    body_content_list.append(h1_content)

    # h2コンテンツ
    review_info_content = [
        tag('h2', 'レビュー情報'),
        tag('h3', tag('a', '商品レビューページ(Amazon)', href=mapped_data.link)),
        tag('h3', 'メーカー:{}'.format(mapped_data.maker)),
        tag('h3', '評価:{}'.format(mapped_data.average_stars)),
        tag('h3', 'レビュー数:{}'.format(mapped_data.total_review)),
        tag('h3', '総文数:{}'.format(mapped_data.total_text)),
    ]
    body_content_list.extend(review_info_content)

    # heatmapコンテンツ
    heatmap_content_list = [tag('h2', '属性別での文分布')]
    attr_to_star_map = mapped_data.mapping
    heatmap_dict, anchor_dict = self._reorganize_mapped_data(attr_to_star_map)
    heatmap_table = self._create_heatmap_table(heatmap_dict, anchor_dict)
    heatmap_content_list.append(heatmap_table)
    body_content_list.extend(heatmap_content_list)

    # 属性別のレビュー列挙
    enum_content_list = self._itemize_text_by_attr_and_star(attr_to_star_map,
                                                            anchor_dict)
    body_content_list.extend(enum_content_list)

    # bodyコンテンツ
    body = organize_contents(body_content_list, 'body')
    return body
예제 #8
0
 def _make_head_content(self, product_name: str) -> str:
   """head コンテンツの作成"""
   title = tag('title', product_name)
   head_content_list = [*self.head_contents, title]
   head = organize_contents(head_content_list, 'head')
   return head