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

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

新規登録して質問してみよう
ただいま回答率
85.50%
スクレイピング

スクレイピングとは、公開されているWebサイトからページ内の情報を抽出する技術です。

Python 3.x

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

Scrapy

Scrapyは、Pythonで開発されたオープンソースソフトウェアです。スクレイピングという、Webサービスから必要な情報を取り出したり自動操作をしたりする技術を使うものです。

Q&A

1回答

2796閲覧

scrapyでcallback先で、callback前の変数値を利用したい

youme23

総合スコア6

スクレイピング

スクレイピングとは、公開されているWebサイトからページ内の情報を抽出する技術です。

Python 3.x

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

Scrapy

Scrapyは、Pythonで開発されたオープンソースソフトウェアです。スクレイピングという、Webサービスから必要な情報を取り出したり自動操作をしたりする技術を使うものです。

0グッド

0クリップ

投稿2018/08/26 03:55

編集2022/01/12 10:55

前提・実現したいこと

scrapyで起点となるurlから取得したテキストをparseした得られた画像urlを元に画像をダウンロードする処理をする。
このとき、画像ファイル名の付け方で悩んでいる。
ImageItemクラスで定義して、callbackを利用すればよいのか、何もcallbackせずに、self.parseメソッド上に画像のダウンロード処理を入れて、
普通にファイル名を生成するべきなのか。

該当のソースコード

import scrapy,hashlib,json class ExampleSpider(scrapy.Spider): name = 'example-spider' allowed_domains = ['example.com'] start_urls = ['https://example.com/specify_url'] def start_requests(self): urls = self.start_urls for url in urls: yield scrapy.Request(url=url, callback=self.parse) def parse(self, response): info_data = response.(なんらかのparse処理) info_data = json.loads(info_data) yield { "title" : info_data["title"] } image_url = info_data["image_url"] image_blob = scrapy.Request(url=image_url ) ## もしくは image_blob = (self.get_imageを呼び出す何らかの画像取得処理) image_hash = hashlib.sha512(image_blob).hexdigest() image_filename = info_data["title"]+"-"+image_hash+"-"+image_url.name yield{ image_url:image_url ,image_blobdata : image_blob , image_hash : image_hash , image_filename : image_filename } def get_image(self, response): image_url = info_data["image_url"] image_blob = scrapy.Request(url=image_url ) image_hash = hashlib.sha512(image_blob).hexdigest() image_filename = info_data["title"]+"-"+image_hash+"-"+image_url.name yield{ image_url:image_url ,image_blobdata : image_blob , image_hash : image_hash , image_filename : image_filename }

特定のurlから複数の画像urlが取得可能であり、画像特有の処理があるため、
画像には特別に別のクラスを導入するべきかと思います。
しかし、callback先にImageItemクラスを生成して、
画像特有の処理をする際に、画像ファイル名に、callback元の変数値(例えばtitle)を利用するので、どのような処理をすればよいかわかりません。

ただし、画像特有の処理と言っても、
ある1つの特定urlに対して、複数の画像が存在しても、
それらは異なるタグ(image_url,image_big_url)のようなもので、
最終的な保存のときの、Itemクラスでのkey名は、
・image_url
・image_hash
・image_blob
・image_filename

・image_big_url
・image_big_hash
・image_big_blob
・image_big_filename

のような区別を行うため、
callback先でyieldによる保存を行うにしても、このようなkey名の変更に対応できるようなcallback関数の呼び出し方が必要です。

となると、素直にcallbackせずに、self.parse内に希望の画像特有の処理を入れるべきかなと悩んでます。

##最終的な処理

https://example.com/specify_urlから特定テキストをparse処理し、
json形式(というよりdict形式)にして、info_dataに格納します。
info_dataは、title,(何かのidなど),image_url,image_big_urlです。

これを画像特有の処理を行い、最終的には以下のkeyを持つitemクラスのインスタンスを生成します。

・特定テキストの取得時刻
・title
・(何かのidなど)

・image_url
・image_hash
・image_blob
・image_filename

・image_big_url
・image_big_hash
・image_big_blob
・image_big_filename

そして、csvかdbに保存するつもりです。

補足情報(FW/ツールのバージョンなど)

python 3.6.4
scrapy 1.5.1

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

Requestのmetaに受け継ぎたい情報を格納してRequestをyieldするのが合っているように見えます。

class ExampleSpider(scrapy.Spider): (略) def parse(self, response): (略) image_url = info_data["image_url"] additional_data = { (必要な情報を格納した辞書を作る) 'hoge': hoge_data, } # イメージのURLをリクエストする。コールバックはparse_imageを指定 yield scrapy.Request(url=image_url, meta=additional_data, callback=parse_image) def parse_image(self, response): # parseから渡ってくるデータを取り出す hoge_data = response.meta['hoge'] (なんかhoge_detaを使った処理) yield なんかデータ

参考
https://doc.scrapy.org/en/latest/topics/request-response.html#passing-additional-data-to-callback-functions

投稿2018/08/26 13:28

編集2018/08/26 13:29
quickquip

総合スコア11029

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問