Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
Help us understand the problem. What is going on with this article?

初めてscrapyを使ってみた

会社の人にIOTをやる会社を調べてくれと言われたので、
「IOT 会社」でググれば、いろんな情報が出てきます。
最後に、https://hnavi.co.jp (発注ナビ)に辿り着きました。
社名、資本金、住所、ホームページ、これくらいの情報でいいかなと。
Bs4はあえて使わずに、scrapyを使ってみようと思います。
(環境 python 3.8 + vscode)
1.scrapyをinstall
terminalで

pip3 install scrapy

twistedのinstallにて
windows vc++ 14 のbuilt tool がないと怒られた、でを落として、
OK
2. scrapyのプロジェクト作成
scrapy create

2. HTML解析
「iot」で検索すると、urlは
https://hnavi.co.jp/search/iot
で検索結果が出る
2ページ目は,https://hnavi.co.jp/search/iot/2 
そのURLらをターゲットにしてやっていこうと

scrapy のshell 起動

scrapy shell https://hnavi.co.jp/search/iot

2020-12-29 18:46:14 [scrapy.core.engine] DEBUG: Crawled (200)  (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    
[s]   item       {}
[s]   request    
[s]   response   <200 https://hnavi.co.jp/search/iot/>
[s]   settings   
[s]   spider     
[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

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で試す:

response.css('div .page-skill__content__company__head').css('h3 a::attr(href)')

結果
<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/'>
 

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

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())

ページとか考えずべた書き、一旦リンク取得した。

scrapy crawl hnav-iot --nolog

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/

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

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)

実行

scrapy crawl iotDetail --nolog 

結果
画像2.png

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

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

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away