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

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

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

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

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Scrapy

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

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

Q&A

0回答

260閲覧

scrapyでクロールする際動作が安定しない

egg_gogo285

総合スコア16

スクレイピング

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

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Scrapy

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

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

0グッド

0クリップ

投稿2018/11/30 19:53

scrapyを用いて以下のページのaタグのhref属性をとってきてDBに保存することを試みています。
(またどのページからのリンクされているのかの情報も合わせてDBに格納したいです。)

http://news.livedoor.com/article/detail/15637521/
https://gendai.ismedia.jp/articles/-/58626
まずこれらのURLをstart_urls.txtというファイルに定義しておきます。

以下ソースコードです

# スパイダー定義 # クロール起点をテキストファイルから取得(シードから深さ1だけクロールする) class SpiderSpider(scrapy.Spider): name = 'spider' allowed_domains = [] start_urls = () sharp = re.compile('#') java = re.compile('javascript') mailto = re.compile('mailto') href_list = [] def __init__(self, *args, **kwargs): super(SpiderSpider, self).__init__(*args, **kwargs) # クロール起点ノードを定義したファイルをオープン f = open("start_urls.txt") urls = f.readlines() f.close() # 末尾の改行や空行だけのものを削除し、start_urlsにいれる self.start_urls = [url.rstrip("\n") for url in urls if url != "\n"] def parse(self, response): seed_node = ScrapyProjectItem() seed_node['url'] = response.url seed_node['type'] = "seed" seed_node['color'] = "red" seed_node['source'] = 0 yield seed_node self.href_list.__init__() self.href_list.extend(response.xpath('//body//a/@href').extract()) self.href_list = list(set(self.href_list)) for href in self.href_list: if href is not None and\ self.sharp.search(href.lower()) is\ self.java.search(href.lower()) is\ self.mailto.search(href.lower()) is None: href = response.urljoin(href) node = ScrapyProjectItem() node['url'] = href node['type'] = "normal" node['color'] = "white" node['source'] = response.url yield node

以下pipeline処理です

class ScrapySpiderPipeline(object): conn = None dname = None def __init__(self, settings): self.dname = settings.get("DATABASE_NAME") self.start_nodes_filename = settings.get("START_URLS") @classmethod def from_crawler(cls, crawler, *args, **kwargs): return cls(settings=crawler.settings) def open_spider(self, spider): self.conn = sqlite3.connect(self.dname) try: self.conn.execute("DROP TABLE IF EXISTS vertices") self.conn.execute("DROP TABLE IF EXISTS edges") self.conn.execute( "CREATE TABLE IF NOT EXISTS vertices (url TEXT UNIQUE , nodetype TEXT, color TEXT, auth, hub)" ) self.conn.execute( "CREATE TABLE IF NOT EXISTS edges (source, target, weight)" ) self.conn.execute( "CREATE UNIQUE INDEX edgeindex ON edges(source, target)" ) except sqlite3.Error: print("sqlite3.Error occurred when CREATE.", sqlite3.Error.args[0]) self.conn.close() exit(-1) self.conn.commit() def close_spider(self, spider): # クロールされる順序によってはシードと判定されない場合もあるのでシード情報を上書きする. # これはstart_urlsに同じドメインのサイトを複数入れたときなどを想定しています。 # クロール起点ノードを定義したファイルをオープン filename = "../" + self.start_nodes_filename with open(filename) as f: urls = f.readlines() # 末尾の改行や空行だけのものを削除し、start_urls_listにいれる start_urls_list = [url.rstrip("\n") for url in urls if url != "\n"] # start_urls_list内のノードに関してDBを更新する. for st_url in start_urls_list: self.conn.execute("UPDATE vertices set nodetype='seed', color='red' where url=\'" + st_url + "\'") self.conn.commit() self.conn.close() def process_item(self, item, spider): try: self.conn.execute("INSERT INTO vertices VALUES (?,?,?,?,?)", (item["url"], item["type"], item["color"], 0, 0)) except sqlite3.IntegrityError: pass if item["source"] != 0: try: self.conn.execute("INSERT INTO edges VALUES (?,?,?)", (item["source"], item["url"], 0)) except sqlite3.IntegrityError: pass self.conn.commit() return item

連続で実行してみると拾ってくるitemの数が100以上増減していて動作が安定していないようです。
ログ出力を確認しても以下のようにitem数が大幅に異なっています。

1度目の実行

{'downloader/request_bytes': 1304, 'downloader/request_count': 4, 'downloader/request_method_count/GET': 4, 'downloader/response_bytes': 39756, 'downloader/response_count': 4, 'downloader/response_status_count/200': 4, 'finish_reason': 'finished', 'finish_time': datetime.datetime(2018, 11, 30, 19, 43, 16, 416240), 'item_scraped_count': 355, 'log_count/DEBUG': 360, 'log_count/ERROR': 1, 'log_count/INFO': 8, 'memusage/max': 50589696, 'memusage/startup': 50589696, 'response_received_count': 4, 'scheduler/dequeued': 2, 'scheduler/dequeued/memory': 2, 'scheduler/enqueued': 2, 'scheduler/enqueued/memory': 2, 'start_time': datetime.datetime(2018, 11, 30, 19, 43, 9, 964071)}

2度目の実行

2018-12-01 04:43:31 [scrapy.statscollectors] INFO: Dumping Scrapy stats: {'downloader/request_bytes': 1304, 'downloader/request_count': 4, 'downloader/request_method_count/GET': 4, 'downloader/response_bytes': 39756, 'downloader/response_count': 4, 'downloader/response_status_count/200': 4, 'finish_reason': 'finished', 'finish_time': datetime.datetime(2018, 11, 30, 19, 43, 31, 666102), 'item_scraped_count': 107, 'log_count/DEBUG': 112, 'log_count/ERROR': 1, 'log_count/INFO': 8, 'memusage/max': 50585600, 'memusage/startup': 50585600, 'response_received_count': 4, 'scheduler/dequeued': 2, 'scheduler/dequeued/memory': 2, 'scheduler/enqueued': 2, 'scheduler/enqueued/memory': 2, 'start_time': datetime.datetime(2018, 11, 30, 19, 43, 26, 519444)} 2018-12-01 04:43:31 [scrapy.core.engine] INFO: Spider closed (finished)

2度目にitemとして得られなかったのは
http://news.livedoor.com/article/detail/15637521/
<div class="rankingBockBody">タグの中などが多いようなのですが
原因がspiderにあるのかpipelineにあるのかも全くわかりません。。

分野に詳しい方、ご意見を聞かせてほしいです、、

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

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

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

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

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

guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだ回答がついていません

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

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

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問