Scrapy を使ってWebページのデータの取得を行なっています。
環境としてはCentOSのpython3.6(pyenv環境)となります。
1 2 3 4 5 6 7 |
# cat /etc/redhat-release CentOS Linux release 7.5.1804 (Core) # python -V Python 3.6.6 |
ただ、sqlite-develを入れないと後ほど、以下のエラーが出たのでsqliteをインストールして再度python3.6をインストールしておきます。
1 2 3 |
ModuleNotFoundError: No module named '_sqlite3' |
1 2 3 4 5 |
# yum -y install sqlite-devel # pyenv install 3.6.6 |
Scrapyのインストール
さて、それでは Scrapy のインストールを行います。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
# pip install scrapy Collecting scrapy Downloading https://files.pythonhosted.org/packages/5d/12/a6197eaf97385e96fd8ec56627749a6229a9b3178ad73866a0b1fb377379/Scrapy-1.5.1-py2.py3-none-any.whl (249kB) 100% |████████████████████████████████| 256kB 11.1MB/s Collecting PyDispatcher>=2.0.5 (from scrapy) Downloading https://files.pythonhosted.org/packages/cd/37/39aca520918ce1935bea9c356bcbb7ed7e52ad4e31bff9b943dfc8e7115b/PyDispatcher-2.0.5.tar.gz Collecting w3lib>=1.17.0 (from scrapy) Downloading https://files.pythonhosted.org/packages/37/94/40c93ad0cadac0f8cb729e1668823c71532fd4a7361b141aec535acb68e3/w3lib-1.19.0-py2.py3-none-any.whl Collecting queuelib (from scrapy) Downloading https://files.pythonhosted.org/packages/4c/85/ae64e9145f39dd6d14f8af3fa809a270ef3729f3b90b3c0cf5aa242ab0d4/queuelib-1.5.0-py2.py3-none-any.whl Collecting six>=1.5.2 (from scrapy) Downloading https://files.pythonhosted.org/packages/67/4b/141a581104b1f6397bfa78ac9d43d8ad29a7ca43ea90a2d863fe3056e86a/six-1.11.0-py2.py3-none-any.whl Collecting pyOpenSSL (from scrapy) Downloading https://files.pythonhosted.org/packages/96/af/9d29e6bd40823061aea2e0574ccb2fcf72bfd6130ce53d32773ec375458c/pyOpenSSL-18.0.0-py2.py3-none-any.whl (53kB) 100% |████████████████████████████████| 61kB 15.7MB/s Collecting parsel>=1.1 (from scrapy) Downloading https://files.pythonhosted.org/packages/96/69/d1d5dba5e4fecd41ffd71345863ed36a45975812c06ba77798fc15db6a64/parsel-1.5.1-py2.py3-none-any.whl Collecting lxml (from scrapy) Downloading https://files.pythonhosted.org/packages/03/a4/9eea8035fc7c7670e5eab97f34ff2ef0ddd78a491bf96df5accedb0e63f5/lxml-4.2.5-cp36-cp36m-manylinux1_x86_64.whl (5.8MB) 100% |████████████████████████████████| 5.8MB 3.5MB/s Collecting service-identity (from scrapy) Downloading https://files.pythonhosted.org/packages/e9/7c/2195b890023e098f9618d43ebc337d83c8b38d414326685339eb024db2f6/service_identity-18.1.0-py2.py3-none-any.whl Collecting Twisted>=13.1.0 (from scrapy) Could not find a version that satisfies the requirement Twisted>=13.1.0 (from scrapy) (from versions: ) No matching distribution found for Twisted>=13.1.0 (from scrapy) |
Twisted 13.1.0以上が必要のためインストールに失敗しました。
非同期処理のためのフレームワークであるTwistedをインストールしてみます。
1 2 3 4 5 6 |
# pip install Twisted Collecting Twisted Could not find a version that satisfies the requirement Twisted (from versions: ) No matching distribution found for Twisted |
pipで入らないようなのでソースからのインストールを行います。
1 2 3 4 5 6 7 |
# cd /tmp # wget https://twistedmatrix.com/Releases/Twisted/17.5/Twisted-17.5.0.tar.bz2 # tar -jxvf Twisted-17.5.0.tar.bz2 # cd Twisted-17.5.0 # python setup.py install |
こちらでTwistedのインストールが完了しました。
再度、Scrapyのインストールを行います。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
# pip install scrapy # scrapy Scrapy 1.5.1 - no active project Usage: scrapy <command> [options] [args] Available commands: bench Run quick benchmark test fetch Fetch a URL using the Scrapy downloader genspider Generate new spider using pre-defined templates runspider Run a self-contained spider (without creating a project) settings Get settings values shell Interactive scraping console startproject Create new project version Print Scrapy version view Open URL in browser, as seen by Scrapy [ more ] More commands available when run from project directory Use "scrapy <command> -h" to see more info about a command |
無事インストールが完了しました。
プロジェクトの作成
次にプロジェクトの作成を行います。
ここでは「sample_crawler」というプロジェクトを作成しています。
1 2 3 4 5 6 7 8 9 |
# scrapy startproject sample_crawler New Scrapy project 'sample_crawler', using template directory '/usr/bin/.pyenv/versions/3.6.6/lib/python3.6/site-packages/scrapy/templates/project', created in: /usr/local/work/scrapy-test/sample_crawler You can start your first spider with: cd sample_crawler scrapy genspider example example.com |
無事作成されました。
プロジェクトの初期ファイルは以下のようになっています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
# cd sample_crawler/ # tree . ├── sample_crawler │ ├── __init__.py │ ├── items.py │ ├── middlewares.py │ ├── pipelines.py │ ├── __pycache__ │ ├── settings.py │ └── spiders │ ├── __init__.py │ └── __pycache__ └── scrapy.cfg |
ここで大事になるのは以下の3つです。
spidersフォルダ | スクレイピング対象の定義など記載したファイルを置く |
items.py | スクレイピンした後に取得するデータを定義するクラスファイル |
settings.py | 動作の設定を決める設定ファイル |
まず、スクレイピング対象の定義ファイルを以下のコマンドで作成します。
「devcolla」という定義ファイルを作り、「developer-collaboration.com」のサイトを対象にしています。
1 2 3 4 5 |
# scrapy genspider devcolla developer-collaboration.com Created spider 'devcolla' using template 'basic' in module: sample_crawler.spiders.devcolla |
「sample_crawler/spiders/devcolla.py」というファイルができます。
ファイルを確認してみます。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
# -*- coding: utf-8 -*- import scrapy class DevcollaSpider(scrapy.Spider): name = 'devcolla' allowed_domains = ['developer-collaboration.com'] start_urls = ['http://developer-collaboration.com/'] def parse(self, response): pass |
「start_urls = ['http://developer-collaboration.com/']」の行からクロールが始まっており、こちらは複数のサイトを指定することができます。
こちらの取得したHTMLソースがparse()メソッドの第二引数responseに渡されています。
また、「items.py」を見てみます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
# -*- coding: utf-8 -*- # Define here the models for your scraped items # # See documentation in: # https://doc.scrapy.org/en/latest/topics/items.html import scrapy class SampleCrawlerItem(scrapy.Item): # define the fields for your item here like: # name = scrapy.Field() pass |
SampleCrawlerItemという定義が空でなされています。
それではまず、「items.py」を以下のように編集してみます。
「title」と「url」を受け取ります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
# -*- coding: utf-8 -*- # Define here the models for your scraped items # # See documentation in: # https://doc.scrapy.org/en/latest/topics/items.html import scrapy class SampleCrawlerItem(scrapy.Item): title = scrapy.Field() url = scrapy.Field() |
また、「devcolla.py」は以下のように修正します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
# -*- coding: utf-8 -*- import scrapy from sample_crawler.items import SampleCrawlerItem class DevcollaSpider(scrapy.Spider): name = 'devcolla' allowed_domains = ['developer-collaboration.com'] start_urls = ['http://developer-collaboration.com/'] def parse(self, response): for quote in response.css('article.post-list'): item = SampleCrawlerItem() item['title'] = quote.css('h1.entry-title::text').extract_first() item['url'] = quote.css('a::attr(href)').extract_first() yield item |
「from sample_crawler.items import SampleCrawlerItem」の行で定義クラスを読み込みます。
「for quote in response.css('article.post-list'):」の行で「article.post-list」のCSSのタグのデータを取得しています。
「item = SampleCrawlerItem()」の行で定義ファイルのオブジェクトを生成します。
その下の2行で取得する要素を設定しています。
ここでは記事のタイトルとURLをトップページから取得しています。
それでは実際に動かしてみます。
以下のコマンドでスクレイピングすることができます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 |
# scrapy crawl devcolla 2018-12-07 15:20:47 [scrapy.utils.log] INFO: Scrapy 1.5.1 started (bot: sample_crawler) 2018-12-07 15:20:47 [scrapy.utils.log] INFO: Versions: lxml 4.2.5.0, libxml2 2.9.8, cssselect 1.0.3, parsel 1.5.1, w3lib 1.19.0, Twisted 17.5.0, Python 3.6.6 (default, Dec 7 2018, 13:39:15) - [GCC 4.8.5 20150623 (Red Hat 4.8.5-28)], pyOpenSSL 18.0.0 (OpenSSL 1.1.0j 20 Nov 2018), cryptography 2.4.2, Platform Linux-3.10.0-862.14.4.el7.x86_64-x86_64-with-centos-7.5.1804-Core 2018-12-07 15:20:47 [scrapy.crawler] INFO: Overridden settings: {'BOT_NAME': 'sample_crawler', 'NEWSPIDER_MODULE': 'sample_crawler.spiders', 'ROBOTSTXT_OBEY': True, 'SPIDER_MODULES': ['sample_crawler.spiders']} 2018-12-07 15:20:47 [scrapy.middleware] INFO: Enabled extensions: ['scrapy.extensions.corestats.CoreStats', 'scrapy.extensions.telnet.TelnetConsole', 'scrapy.extensions.memusage.MemoryUsage', 'scrapy.extensions.logstats.LogStats'] 2018-12-07 15:20:47 [scrapy.middleware] INFO: Enabled downloader middlewares: ['scrapy.downloadermiddlewares.robotstxt.RobotsTxtMiddleware', 'scrapy.downloadermiddlewares.httpauth.HttpAuthMiddleware', 'scrapy.downloadermiddlewares.downloadtimeout.DownloadTimeoutMiddleware', 'scrapy.downloadermiddlewares.defaultheaders.DefaultHeadersMiddleware', 'scrapy.downloadermiddlewares.useragent.UserAgentMiddleware', 'scrapy.downloadermiddlewares.retry.RetryMiddleware', 'scrapy.downloadermiddlewares.redirect.MetaRefreshMiddleware', 'scrapy.downloadermiddlewares.httpcompression.HttpCompressionMiddleware', 'scrapy.downloadermiddlewares.redirect.RedirectMiddleware', 'scrapy.downloadermiddlewares.cookies.CookiesMiddleware', 'scrapy.downloadermiddlewares.httpproxy.HttpProxyMiddleware', 'scrapy.downloadermiddlewares.stats.DownloaderStats'] 2018-12-07 15:20:47 [scrapy.middleware] INFO: Enabled spider middlewares: ['scrapy.spidermiddlewares.httperror.HttpErrorMiddleware', 'scrapy.spidermiddlewares.offsite.OffsiteMiddleware', 'scrapy.spidermiddlewares.referer.RefererMiddleware', 'scrapy.spidermiddlewares.urllength.UrlLengthMiddleware', 'scrapy.spidermiddlewares.depth.DepthMiddleware'] 2018-12-07 15:20:47 [scrapy.middleware] INFO: Enabled item pipelines: [] 2018-12-07 15:20:47 [scrapy.core.engine] INFO: Spider opened 2018-12-07 15:20:47 [scrapy.extensions.logstats] INFO: Crawled 0 pages (at 0 pages/min), scraped 0 items (at 0 items/min) 2018-12-07 15:20:47 [scrapy.extensions.telnet] DEBUG: Telnet console listening on 127.0.0.1:6023 2018-12-07 15:20:49 [scrapy.core.engine] DEBUG: Crawled (200) <GET http://developer-collaboration.com/robots.txt> (referer: None) 2018-12-07 15:20:50 [scrapy.core.engine] DEBUG: Crawled (200) <GET http://developer-collaboration.com/> (referer: None) 2018-12-07 15:20:50 [scrapy.core.scraper] DEBUG: Scraped from <200 http://developer-collaboration.com/> {'title': 'Google Cloud Platform を Cloud SDKで設定(CentOS7)', 'url': 'https://developer-collaboration.com/2018/11/13/google-cloud-platform-cloud-sdk-centos/'} 2018-12-07 15:20:50 [scrapy.core.scraper] DEBUG: Scraped from <200 http://developer-collaboration.com/> {'title': 'curlでSSL接続しようとすると「curl: (35) SSL connect error」のエラーが出た', 'url': 'https://developer-collaboration.com/2018/11/08/curl-ssl-error/'} 2018-12-07 15:20:50 [scrapy.core.scraper] DEBUG: Scraped from <200 http://developer-collaboration.com/> {'title': 'Railsアプリの CentOS7 + nginx 環境を 無料 の SSL 「Let’s Encrypt」でSSL化', 'url': 'https://developer-collaboration.com/2018/11/05/lets-encrypt-nginx-centos7-rails/'} 2018-12-07 15:20:50 [scrapy.core.scraper] DEBUG: Scraped from <200 http://developer-collaboration.com/> {'title': 'kibana と Beats (metricbeat)を使ってサーバのパフォーマンスデータを可視化する', 'url': 'https://developer-collaboration.com/2018/10/28/kibana-metricbeats01/'} 2018-12-07 15:20:50 [scrapy.core.scraper] DEBUG: Scraped from <200 http://developer-collaboration.com/> {'title': '「outlook.jp」や「hotmail.co.jp」宛のメールがエラーになった時の対応', 'url': 'https://developer-collaboration.com/2018/10/27/outlook-jp-mail-error/'} 2018-12-07 15:20:50 [scrapy.core.scraper] DEBUG: Scraped from <200 http://developer-collaboration.com/> {'title': 'Python で Elasticsearch の settings と mappings を作成', 'url': 'https://developer-collaboration.com/2018/10/24/python-elasticsearch-create-settings-mappings/'} 2018-12-07 15:20:50 [scrapy.core.scraper] DEBUG: Scraped from <200 http://developer-collaboration.com/> {'title': 'Ajax での複数項目の JSON ファイルの取得と読み込みについて', 'url': 'https://developer-collaboration.com/2018/10/19/ajax-multidata-json-get/'} 2018-12-07 15:20:50 [scrapy.core.scraper] DEBUG: Scraped from <200 http://developer-collaboration.com/> {'title': 'さくらVPS の CentOS7 サーバに Elasticsearch 6.2.0 と Sudachi をインストールしてみる', 'url': 'https://developer-collaboration.com/2018/10/11/sakura-vps-centos7-elasticsearch-6-2-sudachi-install/'} 2018-12-07 15:20:50 [scrapy.core.scraper] DEBUG: Scraped from <200 http://developer-collaboration.com/> {'title': 'Django2.1.1 を使ってログインを実装する', 'url': 'https://developer-collaboration.com/2018/10/05/django-login01/'} 2018-12-07 15:20:50 [scrapy.core.scraper] DEBUG: Scraped from <200 http://developer-collaboration.com/> {'title': 'CentOS7 に Hadoop と Mahout を入れて機械学習を試してみる', 'url': 'https://developer-collaboration.com/2018/10/03/centos7-hadoop-mahout-install/'} 2018-12-07 15:20:50 [scrapy.core.engine] INFO: Closing spider (finished) 2018-12-07 15:20:50 [scrapy.statscollectors] INFO: Dumping Scrapy stats: {'downloader/request_bytes': 462, 'downloader/request_count': 2, 'downloader/request_method_count/GET': 2, 'downloader/response_bytes': 37412, 'downloader/response_count': 2, 'downloader/response_status_count/200': 2, 'finish_reason': 'finished', 'finish_time': datetime.datetime(2018, 12, 7, 6, 20, 50, 139054), 'item_scraped_count': 10, 'log_count/DEBUG': 13, 'log_count/INFO': 7, 'memusage/max': 44695552, 'memusage/startup': 44695552, 'response_received_count': 2, 'scheduler/dequeued': 1, 'scheduler/dequeued/memory': 1, 'scheduler/enqueued': 1, 'scheduler/enqueued/memory': 1, 'start_time': datetime.datetime(2018, 12, 7, 6, 20, 47, 356564)} 2018-12-07 15:20:50 [scrapy.core.engine] INFO: Spider closed (finished) |
無事、サイトからデータを取得し、クラス定義されたオブジェクトにデータが格納されました。
最初の確認としての使い方は以上になります。
★関連記事
・Scrapyでデータ取得でクローリングで取得したURLから検索する(Scrapy その2)
・CentOS7でscrapy-splashを使ってJavaScriptの解析(Scrapy その3)
・Scrapyでデータの保存をmongodbにして見る(Scrapy その4)
・CentOS7でscrapy-splashを使ってJavaScriptの解析 その2(Scrapy その5)
このブログは株式会社CoLabMixによる技術ブログです。
GCP、AWSなどでのインフラ構築・運用や、クローリング・分析・検索などを主体とした開発を行なっています。
Ruby on RailsやDjango、Pythonなどの開発依頼などお気軽にお声がけください。
開発パートナーを増やしたいという企業と積極的に繋がっていきたいです。