python3+scrapyで週間Top1のユーザのすべての記事を収集してみる

### 一、はじめに
scrapyとは、、Pythonで書かれた無料のオープンソースのWebクロールフレームワークです。

今、ユーザーランキングの週間のTOP1のユーザが@shimajiri さんです。
これからはpython3+scrapyを使って@shimajiri さんのすべての記事を収集してみよう。

### 二、事前準備
  
####１.環境構築：

- OS:Windows 10
- 言語：python 3.7.4
- フレームワーク：scrapy 1.7.3

   
####２．プロジェクト作成
  以下のコマンドでプロジェクトを作ろう。
> scrapy startproject scrapy_demo1

![scrapystart.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/225740/33829888-34d2-0584-ef43-6e2995bae428.png)

### 三、ソース実装
  
####１.items.pyの実装

  今回は主に記事のdate、title、urlなどの情報を収集するため、それらの情報を基に、itemのクラスを作ろう

```python:items.py
 # -*- coding: utf-8 -*-
 # Define here the models for your scraped items
 # See documentation in:
 # https://docs.scrapy.org/en/latest/topics/items.html

 import scrapy

 class ScrapyDemo1Item(scrapy.Item):
       # define the fields for your item here like:
       # 日時
       date = scrapy.Field()
       # タイトル
       title = scrapy.Field()
       # URL
       url = scrapy.Field()
```  
####２.spider_demo1.pyの実装
spider_demo1.pyとは、ターゲットURLをクロールして、情報を抽出し、解析すること。
まずは、scrapy_demo1\spidersのフォルダに入って以下のコマンドでspider_demo1.pyを作成する
> scrapy genspider -t basic spider_demo1 qiita.com

![scrapy_spider.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/225740/b223fbb9-c800-58b4-5e05-4b10b8facaa4.png)

こらから、spider_demo1.pyの業務流れを理解し、実装します。

Target Urlは[こちら](https://qiita.com/shimajiri)です。ブラウザで開いて、F12のDEBUGモードで画面の構造がわかることになります。

![画面の構造.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/225740/cca127fc-6ce4-bdaa-cb39-856a49559ae5.png)

だから、実装を続いて、主にparseメソッドを実装する、最後に以下のようにします。
xpathの使い方は[こちら](https://docs.scrapy.org/en/latest/topics/selectors.html)で参考しましょう。

```python:spider_demo1.py
#!/usr/bin/env python
# -*- coding:utf-8 -*-

#import sys
#reload(sys)
#sys.setdefaultencoding("utf-8")

import scrapy
from scrapy_demo1.items import ScrapyDemo1Item

class SpiderDemo1Spider(scrapy.Spider):
    # Spiderの名前(必須)
    name = "spider_demo1"
    # 対象ホスト
    allowed_domains = ["qiita.com"]
    # 対象URLリスト
    start_urls = ["https://qiita.com/shimajiri?page=2","https://qiita.com/shimajiri",]

    def parse(self, response):
        node_list = response.xpath("//article[@class='media ItemLink']")
        print("node_list--------------:",node_list)

        for node in node_list:
            # itemクラスのインスタンスを作り、収集した情報をここに保存
            item = ScrapyDemo1Item()
            # .extract()で 内容をUnicode文字に転換
            url = node.xpath("./div[@class='media__body']/div[@class='ItemLink__title']/a/@href").extract()
            date = node.xpath("./div[@class='media__body']/div[@class='ItemLink__info']/text()").extract()
            title = node.xpath("./div[@class='media__body']/div[@class='ItemLink__title']/a/text()").extract()

            # 日時
            item['date'] = date[0]
            # タイトル
            item['title'] = title[0]
            # リンク
            item['url'] = "https://qiita.com" + url[0]

            # itemのデータをpipelines.pyクラスに渡し、次の処理を続け
            yield item

```

####３.pipelines.pyの実装
　　pipelines.pyクラスとは、SpiderDemo1Spiderからの情報(item)をファイルに書き出す。
　　以下のようにします。実行すれば、収集したデートはscrapydemo1_data.jsonに保存すべきだ。

```python:pipelines.py
# -*- coding: utf-8 -*-
# Define your item pipelines here
#
# Don't forget to add your pipeline to the ITEM_PIPELINES setting
# See: http://doc.scrapy.org/en/latest/topics/item-pipeline.html

import json

class ScrapyDemo1Pipeline(object):
    def __init__(self):
        self.f = open("scrapydemo1_data.json", "w")

    def process_item(self, item, spider):
        content = json.dumps(dict(item), ensure_ascii = False) + ", \n"
        self.f.write(content)
        return item

    def close_spider(self, spider):
        self.f.close()
```

ここまで、すべての製造が終わる

### 四、実行結果
まあ、プロジェクトの下にdataフォルダを作って、以下のコマンドでプロジェクトを実行してみよう。
> scrapy crawl spider_demo1

![spider_excute.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/225740/b6b165f2-e404-6a9a-4e87-8f97c77addf7.png)

問題なければ、scrapydemo1_data.jsonを生成し、その中で@shimajiri さんのすべての記事を収集するはずです。
結果は下記のように出力されます。記事が全部で27件となります。

![result.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/225740/4745f197-9096-5adb-5e81-36473e373014.png)


### 五、最後に
最後まで読んでいただき、ありがとうございます。
@shimajiri さん、ご迷惑をかけましたら、申し訳ございません。

**ソースコードは[こちら](https://github.com/Hyman1993/Python_Demos)でダウンロード可能です**