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

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

ただいまの
回答率

88.93%

ページ構成維持を重視したスクレイピング&CSV保存のベストプラクティス

解決済

回答 2

投稿 編集

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

fukazume

score 62

■経緯

以下のようなプログラムで、スクレイピングしたWebページのHTMLソースを1つのレコードフィールドとしてCSVに保存し、別のWebサービス上でそのソースのHTMLタグやレイアウトの再現性を可能な限り高い形で展開/再構成し表示したいと考えています。

上記を達成するためのスクレイピング手法として私なりに意識したのは以下の点です。
・HTMLタグ付き
・CSVの改行コードを"\r\n" に変更することでHTMLソース内の改行\nと区別

しかし、下記コードを実行しても、CSVとしてレコードのフィールド内にうまく収まってくれません。

# -*- coding: utf-8 -*-
import requests
import csv
from bs4 import BeautifulSoup as bs4

source = './test.csv'
url = 'http://books.toscrape.com/catalogue/a-light-in-the-attic_1000/index.html'
row = []

r = requests.get(url)
soup = bs4(r.content,'lxml')

row.append(soup.find(class_='content'))

with open(source, 'w', encoding="UTF-8") as f:
    writer = csv.writer(f, lineterminator='\r\n', quoting=csv.QUOTE_NONNUMERIC) 
    writer.writerow(row) 

■質問

上記目的を達成するための常套の手法などございましたらヒントなどいただけますと誠にありがたく存じます。

■環境

Windows 10
Python 3.8.3

■CSV出力結果(test.csv)

"<div class=""content"">
<div id=""promotions"">
</div>
<div id=""content_inner"">
<article class=""product_page""><!-- Start of product page -->
<div class=""row"">
<div class=""col-sm-6"">
<div class=""carousel"" id=""product_gallery"">
<div class=""thumbnail"">
<div class=""carousel-inner"">
<div class=""item active"">
<img alt=""A Light in the Attic"" src=""../../media/cache/fe/72/fe72f0532301ec28892ae79a629a293c.jpg""/>
</div>
</div>
</div>
</div>
</div>
<div class=""col-sm-6 product_main"">
<h1>A Light in the Attic</h1>
<p class=""price_color"">£51.77</p>
<p class=""instock availability"">
<i class=""icon-ok""></i>

        In stock (22 available)

</p>
<p class=""star-rating Three"">
<i class=""icon-star""></i>
<i class=""icon-star""></i>
<i class=""icon-star""></i>
<i class=""icon-star""></i>
<i class=""icon-star""></i>
<!-- <small><a href=""/catalogue/a-light-in-the-attic_1000/reviews/"">


                    0 customer reviews

        </a></small>
         --> 


<!-- 
    <a id=""write_review"" href=""/catalogue/a-light-in-the-attic_1000/reviews/add/#addreview"" class=""btn btn-success btn-sm"">
        Write a review
    </a>

 --></p>
<hr/>
<div class=""alert alert-warning"" role=""alert""><strong>Warning!</strong> This is a demo website for web scraping purposes. Prices and ratings here were randomly assigned and have no real meaning.</div>
</div><!-- /col-sm-6 -->
</div><!-- /row -->
<div class=""sub-header"" id=""product_description"">
<h2>Product Description</h2>
</div>
<p>It's hard to imagine a world without A Light in the Attic. This now-classic collection of poetry and drawings from Shel Silverstein celebrates its 20th anniversary with this special edition. Silverstein's humorous and creative verse can amuse the dowdiest of readers. Lemon-faced adults and fidgety kids sit still and read these rhythmic words and laugh and smile and love th It's hard to imagine a world without A Light in the Attic. This now-classic collection of poetry and drawings from Shel Silverstein celebrates its 20th anniversary with this special edition. Silverstein's humorous and creative verse can amuse the dowdiest of readers. Lemon-faced adults and fidgety kids sit still and read these rhythmic words and laugh and smile and love that Silverstein. Need proof of his genius? RockabyeRockabye baby, in the treetopDon't you know a treetopIs no safe place to rock?And who put you up there,And your cradle, too?Baby, I think someone down here'sGot it in for you. Shel, you never sounded so good. ...more</p>
<div class=""sub-header"">
<h2>Product Information</h2>
</div>
<table class=""table table-striped"">
<tr>
<th>UPC</th><td>a897fe39b1053632</td>
</tr>
<tr>
<th>Product Type</th><td>Books</td>
</tr>
<tr>
<th>Price (excl. tax)</th><td>£51.77</td>
</tr>
<tr>
<th>Price (incl. tax)</th><td>£51.77</td>
</tr>
<tr>
<th>Tax</th><td>£0.00</td>
</tr>
<tr>
<th>Availability</th>
<td>In stock (22 available)</td>
</tr>
<tr>
<th>Number of reviews</th>
<td>0</td>
</tr>
</table>
<section>
<div class=""sub-header"" id=""reviews"">
</div>
</section>
</article><!-- End of product page -->
</div>
</div>"
  • 気になる質問をクリップする

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 2

checkベストアンサー

+1

私ならHTMLソースはバイナリとして扱うべきと考えBASE64化して保持します。
バイナリとして扱う(保持)するので、そのCSVに対してソース内の文字検索など行わない前提です。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2020/07/22 16:27 編集

    いつもありがとうございます!BASE64は名前しか知りませんでした。よく調べてみます!バイナリとして扱う場合、出力としては、
    ・1webページに対して1ファイル(バイナリ)という想定でしょうか?
    ・それとも、CSVで他のフィールドと混在する形で、例えば
    "日付","タイトル","特定classなどのHTMLソース(BASE64としてエンコードして)"\n,
    みたいな構造のCSVファイルを想定されているでしょうか?

    わかりにくい説明&質問で申し訳ございません!

    キャンセル

  • 2020/07/22 16:31

    BASE64はバイナリデータを英数文字のみで構成されたテキストに変換する規則です。
    カンマや改行などを含まないテキスト文字列になるので、CSVとして保持できます。
    > ・それとも、CSVで他のフィールドと混在する形で、例えば
    > "日付","タイトル","特定classなどのHTMLソース(BASE64としてエンコードして)"\n,
    > みたいな構造のCSVファイルを想定されているでしょうか?

    こっちの想定ですね。

    キャンセル

  • 2020/07/22 16:42

    ありがとうございます!となると、1ファイルに複数ページ分のHTMLソースをまとめようと思えば可能っぽいですね。こういった基本的な情報操作/ファイル管理でも指針的な情報(=ベストプラクティス)があまり検索でヒットしなかったので大変参考になります。理解にはまだ時間がかかりますが、BASE64、ぜひ深堀りしてみたいと思います!

    キャンセル

+1

やりたいことがちょっとふわっとしているので、的はずれな回答かもしれませんが…

案1 テキストファイル

別のwebサービスとの連携方法にもよりますが、そのままHTMLをテキストファイルに保存するのが一番素直なように思えます。

案2 pickle

別のWebサービスもpythonであれば、Pickleを使うことで持ってきたデータをそのまま書き出しすることができます。
https://qiita.com/hatt0519/items/f1f4c059c28cb1575a93

案3 JSON

別のWebサービスが、Pythonに縛られたくないのであれば、JSON形式あたりを使うのがよいのではないでしょうか。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2020/07/22 16:12

    あいまいな質問に挑んでくださり、また複数の案をご提示くださり、誠にありがとうございます!個別テキストファイルへ書き出すアイディアを思い浮かびませんでした!

    キャンセル

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

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

関連した質問

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