プログラミングマガジン

プログラミングを中心にIT技術をできるだけわかりやすくまとめます。

  • ホーム
  • Python
  • 【Python】「scrapy-selenium」を扱う。
 
 
     
  • サーバー言語  
    • Python
    • Ruby
    • PHP
    • SQL
  •  
  • インフラ  
       
    • AWS
    •  
    • 基本
    • Git
  • Web
       
    • Web開発
    • JavaScript
    • Vue.js
    • React
  •  
  • 設計  
       
    • 実装設計
    • DB設計
  • 問い合わせ
  

【Python】「scrapy-selenium」を扱う。

06.10

  • miyabisan2
  • コメントを書く

この記事は3分で読めます

事前準備

1.Scrapyのプロジェクトを作成する。

1
2
3
scrapy startproject 対象サイト名
cd 対象サイト名
scrapy genspider 任意のspider名 www.xxx.com(サイトURL)

2.projects/プロジェクト配下にchromedriverを配置します。

chromedriverは自分のお使いのChromeのバージョンを調べて検索すれば入手可能です。

3.scrapy-seleniumの設定をする。

以下の公式ページに行きます。Configurationのところに記載がある「1」と「2」の記述をsettings.pyに貼り付けます。

https://github.com/clemfromspace/scrapy-selenium
1
2
3
4
5
6
7
SELENIUM_DRIVER_NAME = 'chrome'
SELENIUM_DRIVER_EXECUTABLE_PATH = r'自分のPCのchromedriverのパス'
SELENIUM_DRIVER_ARGUMENTS=['-headless']  # '--headless' if using chrome instead of firefox
 
DOWNLOADER_MIDDLEWARES = {
    'scrapy_selenium.SeleniumMiddleware': 800
}

なお、firefoxになっていますが、chromeが基本だと思いますのでSELENIUM_DRIVER_NAMEは「chrome」とSELENIUM_DRIVER_EXECUTABLE_PATHは「r'自分のPCのchromedriverのパス'」にそれぞれ書き換えます。(which('chromedriver')という指定でも環境によってはいけるっぽいですが自分の環境だと直接指定しないと動きませんでした。)

その他設定

scrapy-seleniumを使う場合でも最低限のスクレイピングマナーとしてこの辺の設定はしておくようにしましょう。

1
2
3
DOWNLOAD_DELAY = 5 # ダウンロード間隔を秒数で指定
FEED_EXPORT_ENCODING = 'utf-8' # 文字化けしないように設定しておく
ROBOTSTXT_OBEY = True # robots.txtがある場合はそれに従う設定

検索ボックスに入力するサンプル実装

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
import scrapy
from scrapy_selenium import SeleniumRequest
from time import sleep
from selenium.webdriver.common.keys import Keys
from scrapy.selector import Selector
 
class XXXPythonSpider(scrapy.Spider):
    name = "spider名"
 
    # 最初のリクエストはstart_requestsで送る。
    def start_requests(self):
        yield SeleniumRequest(
            url='サイトのURL',
            wait_time=3,
            callback=self.parse
        )
 
    # spiderではレスポンスはparseメソッドで受ける。
    def parse(self, response):
        driver = response.meta['driver']
        search_bar = driver.find_element_by_xpath('検索ボックスのXpath')
        search_bar.send_keys('python')
        sleep(1)
        driver.save_screenshot('xxx.png')
        search_bar.send_keys(Keys.ENTER)
        sleep(3)
        w = driver.execute_script('return document.body.scrollWidth')
        h = driver.execute_script('return document.body.scrollHeight')
        driver.set_window_size(w,h)
        driver.save_screenshot('yyy.png')
        html = driver.page_source
        sel = Selector(text=html)
        for elem in sel.xpath('検索結果のXPath'):
    yield{
        'title': elem.xpath('タイトルのXPath').get(),
        'URL': elem.xpath('URLのXPath').get()
    }

start_requests

scrapy-seleniumを使う場合はseleniumのリクエストとして処理する必要があるのでこれをオーバーライドします。start_urls属性で指定されたURLに対してリクエストを送信します。(ただ、本サンプルでは後続のSeleniumRequestにてurlを別途指定しているので不要になります。)

wait_time

待ち時間です。上記サンプルでは3秒を指定しています。

response

データ型は「scrapy.http.response.html.HtmlResponse」クラスになります。

driver = response.meta('driver')

リクエストしたdriverの情報はレスポンスのmetaデータの中に格納されているので上記のように取り出すことが可能です。このドライバーの情報をもとにxpathやcssで情報を取得したりします。

ここで取得したdriverのデータ型は「selenium.webdriver.chrome.webdriver.WebDriver」というclassになっています。

driver.save_screenshot('xxx.png')

scrapy-seleniumはヘッドレスブラウザが基本なので処理の最後でスクリーンショットを取得するようにする方が無難でしょう。

search_bar.send_keys(Keys.ENTER)

Enterキーを押すアクションです。(clickやsubmitなどのボタンを押すアクションでも良いかもしれません)

driver.set_window_size(w,h)

execute_scriptで実行したJavaScriptで画面サイズを取得した結果を設定しています。通常だと画面のスクリーンショットを取得しても一部しか取得できないのですが、こうすることで画面全体のスクリーンショットを取得できます。

html = driver.page_source、sel = Selector(text=html)

driverは最初に取得したHTMLしか持たないのでその後検索アクションを行った後のHTMLに関しては別途アクション後に取得してあげる必要があります。上記のようにhtmlを取得した後にSelectorオブジェクトに変換してあげる必要があります。

次のページを取得する

上の例のように一覧画面のように複数ページある場合の情報取得処理は以下のようになります。都度SeleniumRequestをしてあげて、次のページがある場合のみ再度SeleniumRequestをしてあげるようにします。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
    def parse(self, response):
        driver = response.meta['driver']
        yield SeleniumRequest(
            url=driver.current_url,
            wait_time=3,
            callback=self.parse_next
        )
 
    def parse_next(self, response):
        for elem in sel.xpath('検索結果のXPath'):
    yield{
        'title': elem.xpath('タイトルのXPath').get(),
        'URL': elem.xpath('URLのXPath').get()
            }
        
        next_page = response.xpath('次へボタンのXPath').get()
        if next_page:
            next_url = response.urljoin(next_page)
            yield SeleniumRequest(
                url=next_url,
                wait_time=3,
                callback=self.parse_next
            )

driver.current_url

現在のURLを再度リクエストしています。

next_url = response.urljoin(next_page)

SeleniumRequestは絶対パス指定が必要になるのでこのように変換してあげる必要があります。

スポンサーリンク
  • 2023 06.10
  • miyabisan2
  • コメントを書く
  • Python
  • Tweets Twitter
  • このエントリーをはてなブックマークに追加
  • LINEで送る

関連記事

  1. 2023 06.09

    【NoSQL】MongoDBの基本

  2. 2023 07.20

    【Python】ValueError: Timeout value connect was エラーの対処

  3. 2023 06.04

    【Python】Scrapyで複数ページを操る。

  4. 2023 06.12

    【Python】「Jupyter Notebook」とは?

  5. 2018 06.18

    【Python】対話実行モード(REPL)。開発環境(PyCharm、IDLEなど)

  6. 2023 06.12

    【Python】pyinstallerでPythonのコードをexe化する。

  • コメント ( 0 )
  • トラックバック ( 0 )
  1. この記事へのコメントはありません。

  1. この記事へのトラックバックはありません。

返信をキャンセルする。

【Python】ScrapyのImagePipelin…

【Python】スプレットシート操作

RETURN TOP

著者プロフィール

エンジニア歴10年で過去に業務系、Webデザイン、インフラ系なども経験あります。現在はWeb系でフロントエンド開発中心です。

詳細なプロフィールはこちら

スポンサーリンク

カテゴリー

  • Android
  • AngularJS
  • API
  • AWS
  • C++
  • CSS
  • cursor
  • C言語
  • DDD
  • DevOps
  • Django
  • Docker
  • Figma
  • Git
  • GitLab
  • GraphQL
  • gRPC
  • Hasura
  • Java
  • JavaScript
  • Kubernetes
  • Laravel
  • linux
  • MySQL
  • Next.js
  • nginx
  • Node.js
  • NoSQL
  • Nuxt.js
  • Oracle
  • PHP
  • Python
  • React
  • Redux
  • Rspec
  • Ruby
  • Ruby on Rails
  • Sass
  • Spring Framework
  • SQL
  • TypeScript
  • Unity
  • Vue.js
  • Webサービス開発
  • Webデザイン
  • Web技術
  • インフラ
  • オブジェクト指向
  • システム開発
  • セキュリティ
  • その他
  • データベース
  • デザインパターン
  • テスト
  • ネットワーク
  • プログラミング全般
  • マイクロサービス
  • マイクロソフト系技術
  • マルチメディア
  • リファクタリング
  • 副業
  • 未分類
  • 業務知識
  • 生成AI
  • 設計
  • 関数型言語
RETURN TOP

Copyright ©  プログラミングマガジン | プライバシーポリシー