初めてscrapyを使ってみた

会社の人にIOTをやる会社を調べてくれと言われたので、
「IOT 会社」でググれば、いろんな情報が出てきます。
最後に、https://hnavi.co.jp （発注ナビ）に辿り着きました。
社名、資本金、住所、ホームページ、これくらいの情報でいいかなと。
Bs4はあえて使わずに、scrapyを使ってみようと思います。
(環境 python 3.8 + vscode)
1．scrapyをinstall
terminalで
<pre>pip3 install scrapy</pre>
twistedのinstallにて
windows vc++ 14 のbuilt tool　がないと怒られた、でを落として、
OK
2. scrapyのプロジェクト作成
<pre>scrapy create</pre> 
2. HTML解析
「iot」で検索すると、urlは
https://hnavi.co.jp/search/iot 
で検索結果が出る
2ページ目は,https://hnavi.co.jp/search/iot/2　
そのURLらをターゲットにしてやっていこうと

scrapy のshell 起動
<pre>scrapy shell https://hnavi.co.jp/search/iot</pre>
<pre>
2020-12-29 18:46:14 [scrapy.core.engine] DEBUG: Crawled (200) <GET https://hnavi.co.jp/search/iot/> (referer: None)
2020-12-29 18:46:15 [asyncio] DEBUG: Using proactor: IocpProactor
[s] Available Scrapy objects:
[s]   scrapy     scrapy module (contains scrapy.Request, scrapy.Selector, etc)
[s]   crawler    <scrapy.crawler.Crawler object at 0x0000027B9D00E280>
[s]   item       {}
[s]   request    <GET https://hnavi.co.jp/search/iot>
[s]   response   <200 https://hnavi.co.jp/search/iot/>
[s]   settings   <scrapy.settings.Settings object at 0x0000027B9D00E310>
[s]   spider     <DefaultSpider 'default' at 0x27b9d506f70>
[s] Useful shortcuts:
[s]   fetch(url[, redirect=True]) Fetch URL and update local objects (by default, redirects are followed)
[s]   fetch(req)                  Fetch a scrapy.Request and update local objects
[s]   shelp()           Shell help (print this help)
[s]   view(response)    View response in a browser
2020-12-29 18:46:15 [asyncio] DEBUG: Using proactor: IocpProactor
</pre>
HTMLを見てみる

```html
<div class="page-skill__content__company__head">
			<h3><a href="https://hnavi.co.jp/spa/02357/">株式会社デザインワン・ジャパン</a></h3>
			<div class="page-skill__content__company__head__review-count">
				<i class="icon icon--bubble-20x19"></i>
				<a href="https://hnavi.co.jp/spa/02357/review/">クチコミ(3件)</a>
			</div>
		</div>
```

会社の名前だけがあるが、詳細も欲しいね。リンクは　https://hnavi.co.jp/spa/XXXX/　
の形になってます。とにかくまずそのリンクを抽出します。
classはpage-skill__xxになるdivタグの下層にある h3タグの中にあるaタグのhref属性です。
shellで試す:
<pre>
response.css('div .page-skill\_\_content\_\_company\_\_head').css('h3 a::attr(href)')
</pre>
結果
<pre>
\<Selector xpath='descendant-or-self::h3/descendant-or-self::*/a/@href' data='https://hnavi.co.jp/spa/02290/'>,
 \<Selector xpath='descendant-or-self::h3/descendant-or-self::*/a/@href' data='https://hnavi.co.jp/spa/02232/'>,
 \<Selector xpath='descendant-or-self::h3/descendant-or-self::*/a/@href' data='https://hnavi.co.jp/spa/02357/'>,
 \<Selector xpath='descendant-or-self::h3/descendant-or-self::*/a/@href' data='https://hnavi.co.jp/spa/02190/'>,
 \<Selector xpath='descendant-or-self::h3/descendant-or-self::*/a/@href' data='https://hnavi.co.jp/ecommerce/01191/'>,
 \<Selector xpath='descendant-or-self::h3/descendant-or-self::*/a/@href' data='https://hnavi.co.jp/spa/02440/'>,
 \<Selector xpath='descendant-or-self::h3/descendant-or-self::*/a/@href' data='https://hnavi.co.jp/spa/02447/'>,
 \<Selector xpath='descendant-or-self::h3/descendant-or-self::*/a/@href' data='https://hnavi.co.jp/ecommerce/01216/'>,
 \<Selector xpath='descendant-or-self::h3/descendant-or-self::*/a/@href' data='https://hnavi.co.jp/web/03759/'>,
 \<Selector xpath='descendant-or-self::h3/descendant-or-self::*/a/@href' data='https://hnavi.co.jp/spa/02442/'>
 </pre>

data=の値はリンクですね。
dataはget()関数で取得できそう。

```python:iotSpider.py
import scrapy
class IotSpider(scrapy.Spider):
    name = 'hnav-iot'
    k = name.split('-')[1]
    
    start_urls = ['http://hnavi.co.jp/search/'+k,
    'http://hnavi.co.jp/search/'+k+'/2',
    'http://hnavi.co.jp/search/'+k+'/3',
    'http://hnavi.co.jp/search/'+k+'/4']
    def parse(self, response):
        for company in response.css('div .page-skill__content__company__head'):
            print (company.css('h3 a::attr(href)')[0].get())
```

ページとか考えずべた書き、一旦リンク取得した。
<pre>
scrapy crawl hnav-iot --nolog
</pre>
<pre>
https://hnavi.co.jp/web/03779/
https://hnavi.co.jp/spa/02360/
https://hnavi.co.jp/spa/02426/
https://hnavi.co.jp/spa/02470/
https://hnavi.co.jp/spa/02445/
https://hnavi.co.jp/web/03648/
https://hnavi.co.jp/spa/02435/
https://hnavi.co.jp/web/03701/
https://hnavi.co.jp/spa/02290/
https://hnavi.co.jp/spa/02232/
https://hnavi.co.jp/spa/02357/
https://hnavi.co.jp/spa/02190/
https://hnavi.co.jp/ecommerce/01191/
https://hnavi.co.jp/spa/02440/
https://hnavi.co.jp/spa/02447/
https://hnavi.co.jp/ecommerce/01216/
https://hnavi.co.jp/web/03759/
https://hnavi.co.jp/spa/02442/
https://hnavi.co.jp/spa/02458/
https://hnavi.co.jp/spa/02351/
https://hnavi.co.jp/spa/02427/
https://hnavi.co.jp/web/03491/
https://hnavi.co.jp/spa/02341/
https://hnavi.co.jp/web/03498/
https://hnavi.co.jp/ecommerce/01204/
https://hnavi.co.jp/spa/02349/
https://hnavi.co.jp/spa/02446/
https://hnavi.co.jp/spa/02418/
https://hnavi.co.jp/spa/02448/
https://hnavi.co.jp/spa/02331/
https://hnavi.co.jp/spa/02452/
https://hnavi.co.jp/spa/02365/
https://hnavi.co.jp/spa/02413/
https://hnavi.co.jp/web/03529/
https://hnavi.co.jp/spa/02388/
https://hnavi.co.jp/spa/02309/
https://hnavi.co.jp/web/03752/
https://hnavi.co.jp/spa/02353/
</pre>

上記のリンクへもう一度getして情報を取ってくる

```python:iotDetail.py
import scrapy
class IotDetailSpider(scrapy.Spider):
    name = 'iotDetail'
    start_urls = [
       'https://hnavi.co.jp/spa/02445/'  #ここにリンクをcopy
,'https://hnavi.co.jp/spa/02351/'
,'https://hnavi.co.jp/web/03701/'
,'https://hnavi.co.jp/web/03498/'
,'https://hnavi.co.jp/spa/02341/'
,'https://hnavi.co.jp/web/03648/'
,'https://hnavi.co.jp/spa/02349/'
,'https://hnavi.co.jp/spa/02418/'
,'https://hnavi.co.jp/spa/02309/'
,'https://hnavi.co.jp/spa/02360/'
,'https://hnavi.co.jp/spa/02458/'
,'https://hnavi.co.jp/ecommerce/01204/'
,'https://hnavi.co.jp/spa/02446/'
,'https://hnavi.co.jp/spa/02435/'
,'https://hnavi.co.jp/web/03491/'
,'https://hnavi.co.jp/web/03752/'
,'https://hnavi.co.jp/spa/02353/'
,'https://hnavi.co.jp/web/03759/'
,'https://hnavi.co.jp/spa/02331/'
,'https://hnavi.co.jp/spa/02448/'
,'https://hnavi.co.jp/spa/02365/'
,'https://hnavi.co.jp/spa/02452/'
,'https://hnavi.co.jp/web/03529/'
,'https://hnavi.co.jp/spa/02413/'
,'https://hnavi.co.jp/spa/02290/'
,'https://hnavi.co.jp/spa/02232/'
,'https://hnavi.co.jp/spa/02357/'
,'https://hnavi.co.jp/spa/02190/'
,'https://hnavi.co.jp/ecommerce/01191/'
,'https://hnavi.co.jp/web/03542/'
,'https://hnavi.co.jp/spa/02447/'
,'https://hnavi.co.jp/spa/02440/'
,'https://hnavi.co.jp/spa/02388/'
,'https://hnavi.co.jp/spa/02427/'
,'https://hnavi.co.jp/spa/02426/'
,'https://hnavi.co.jp/spa/02326/'
,'https://hnavi.co.jp/spa/02442/'
]
def parse(self, response):
        cp_name = response.css('h2.company-info__title::text').get()
        r = {cp_name:{}}
        j = {}
        n=cp_name+"\t"
        # {'dddd':{'ddd':'3333','dddd':'333','dddd':'ddddd'}}
        cp_date ="N/A"
        cp_capital="N/A"
        cp_ceo = "N/A"
        cp_add ="N/A"
        cp_hp ="N/A"
        cp_person="N/A"
        cp_div ="N/A"
        for dtl in response.xpath('//h2[contains(text(), "会社情報")]/following-sibling::table').css('tr'):
            key = dtl.css('th::text').get()
            if key == '資本金':
                cp_capital=dtl.css('td::text').get()
            if key == '設立':
                cp_date=dtl.css('td::text').get()
            if key == '従業員数':
                cp_person=dtl.css('td::text').get()
            if key == '代表取締役':
                cp_ceo=dtl.css('td::text').get()
            if key == '所在地':
                cp_add=dtl.css('td::text').get()
            if key == 'ホームページ':
                cp_hp = dtl.css('td a::attr(href)').get()
            if key == '支部情報':
                cp_div = dtl.css('td::text').get()
            # yield {
            #     key:rst
            # }
        # yield {cp_name:j}
        print(cp_name+"\t"+cp_date+"\t"+cp_capital+"\t"+cp_ceo+"\t"+cp_person+"\t"+cp_add+"\t"+cp_div+"\t"+cp_hp)
        # print(cp_name,cp_date,cp_capital,cp_ceo,cp_person,cp_add,cp_div,cp_hp)
```

実行
<pre>scrapy crawl iotDetail --nolog　</pre>

結果
![画像2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189035/45d9f647-b85b-e873-d353-0c79a6144299.png)

結果をcsvファイルにする場合
scrapy crawl iotDetail --nolog > iotd.csv

二つのスクリプトを一つにして、さらにべた書きをなくす、自動ページングできるように
upgrateしようと思います
メモとして残します。