【Python】Scrapyでクローリングする際のURLを動的に設定する

 こんにちわ、タカです。今日も寒いですね。さて、今回は前回に引き続きPythonの『Scrapy』ネタになります。今回はクローリングするurlを動的に設定する方法を紹介します。

 Scrapyとは、Pythonのクローリング・スクレイピングのフルスタックフレームワークになります。とても強力で便利なフレームワークになり、冗長的な処理をフレームワーク側がやってくれるので、クローリング・スクレイピング処理に集中することができます。

 なお、今回のコードはScrapyのバージョン1.4.0をベースにしたものです。

 さて、前回と同様、まずはScrapyのSpiderクラスのサンプルコードをみていきましょう。


import scrapy

class MySpider(scrapy.Spider):
    name = 'example'
    allowed_domains = ['example.com']
    start_urls = [
        'http://www.example.com/1.html',
        'http://www.example.com/2.html',
        'http://www.example.com/3.html',
    ]

    def parse(self, response):
        for h3 in response.xpath('//h3').extract():
            yield {"title": h3}

 上のコードは、Spiderクラスの基本となるようなコードで、これが実際に何をしているのかを簡単に言うと、「example」という名前のSpiderが、「start_urls」に記載されてあるurlをクローリングして、それぞれのページにある「h3」タグのタイトルを取得しています。

 ここまでは前回の記事と同じになりますが、今回はクローリングするURLを動的に設定してみたいと思います。上のコードで言えば 「start_urls」で設定しているurlを動的に設定するということになります。なお、今回はMySQLからurlを取得するケースを想定してコーディングしたいと思います。

 クローリングするurlを動的に設定するには、「start_requests」メソッドを使います。ちなみに、上のコードでは「start_requests」メソッドは省略されている形になります。

 では、実際にコードを作成していきましょう。

 まず、上のコードを少しカスタマイズして「start_requests」メソッドを追加します。


import scrapy
import MySQLdb
from scrapy.utils.project import get_project_settings

class MySpider(scrapy.Spider):
	name = 'example'

	def start_requests(self):

	def parse(self, response):
		for h3 in response.xpath('//h3').extract():
			yield {"title": h3}


 上のコードでは、まずmysqlを使用するために「MySQLdb」ライブラリと、settings.pyを参照するために「get_project_settings」ライブラリをimportしています。

 また、urlは動的で設定するため、「allowed_domains」と「start_urls」は削除しています。

 つづいて、「start_requests」メソッドにMySqlからデータを取得するコードを追加していきます。


import scrapy
import MySQLdb
from scrapy.utils.project import get_project_settings

class MySpider(scrapy.Spider):
	name = 'example'

	def start_requests(self):

		settings = get_project_settings()

		params = {
			'host': settings.get('MYSQL_HOST', 'localhost'),
			'db': settings.get('MYSQL_DATABASE', ''),
			'user': settings.get('MYSQL_USER',''),
			'passwd': settings.get('MYSQL_PASSWORD',''),
			'charset': settings.get('MYSQL_CHARSET', 'utf8mb4'),
		}

		self.conn = MySQLdb.connect(**params)
		self.c = self.conn.cursor()

		sql = 'select url from urls'
		self.c.execute(sql)
		urls = self.c.fetchall()
		self.conn.commit()

		self.conn.close()

	def parse(self, response):
		for h3 in response.xpath('//h3').extract():
			yield {"title": h3}


 上のコードは、「start_requests」メソッドでDBに接続してデータを取得しているのですが、一つずつ見ていきましょう。

 まず「get_project_settings」を使って、settings.pyのデータを取得しています。そして、「params」ディクショナリにてDB接続に必要な情報を設定しています。ここでは、settings.pyで設定したデータを参照しています。例えば、下のコードはsettings.pyの「MYSQL_HOST」を参照しており、もしsettings.pyに「MYSQL_HOST」データがない場合は、「localhost」を設定するということになります。


settings.get('MYSQL_HOST', 'localhost')


 DB接続に必要な情報を設定したら、下記コードで実際にDBに接続しています。


self.conn = MySQLdb.connect(**params)
self.c = self.conn.cursor()


 DBに接続したら、下記コードでsql文を設定して実行しています。ここでは「urls」というテーブルからurlフィールドを取得すると仮定しています。


sql = 'select url from urls'
self.c.execute(sql)
urls = self.c.fetchall()
self.conn.commit()


 これで、DBからデータを取得することができました。

 そして最後に、取得したurlをクローリングするためのコードを追加します。


import scrapy
import MySQLdb
from scrapy.utils.project import get_project_settings

class MySpider(scrapy.Spider):
	name = 'example'

	def start_requests(self):

		settings = get_project_settings()

		params = {
			'host': settings.get('MYSQL_HOST', 'localhost'),
			'db': settings.get('MYSQL_DATABASE', ''),
			'user': settings.get('MYSQL_USER',''),
			'passwd': settings.get('MYSQL_PASSWORD',''),
			'charset': settings.get('MYSQL_CHARSET', 'utf8mb4'),
		}

		self.conn = MySQLdb.connect(**params)
		self.c = self.conn.cursor()

		sql = 'select url from urls'
		self.c.execute(sql)
		urls = self.c.fetchall()
		self.conn.commit()

		for url in urls:
			yield scrapy.Request(
				url[0],
				callback=self.parse
			)

		self.conn.close()

	def parse(self, response):
		for h3 in response.xpath('//h3').extract():
			yield {"title": h3}


 DBから取得したurlデータをfor文でループしてクローリングリクエストをしています。これでダウンロードされたページは「parse」メソッドでパースされるという形になります。

 なお、補足として「start_requests」メソッドではなく、「__init__」メソッドでも同様のことはできます。

 以上、PythonのScrapyでクローリングするurlを動的に設定する方法でした。ご参考になれば幸いです。

 それでは、今回はここまで。また!

入門 Python 3

オライリージャパン

この記事のまとめ

  • PythonのScrapyでクローリングするurlを動的に設定する

お仕事のご相談・ご依頼
お気軽にお問い合わせください!

お仕事の依頼はこちら

著者プロフィール

Taka

東京、奄美大島を拠点にサーフィンとスノーボードが好きなフリーランスのWebクリエイターです。普段はプログラム書いたりデザインしたり映像作ったりしています。いろいろな人の話しを聞くのが好きなので、このブログを通して多くの人と繋がりが出来たら嬉しいです。noteとInstagramもやっているのでフォローしてくれたらありがたいです!

人気記事

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です