blog

scrapyフレームワーク

スパイダーのデータ抽出は、直接辞書を得ることができますが、item クラスと比較すると、フィールドの欠落チェックが不足しています。...

Dec 17, 2020 · 7 min. read
シェア

I. scrapy入門

Scrapyは、ウェブサイトをクロールして構造化データを抽出するために書かれたアプリケーションフレームワークの純粋なPython実装であり、幅広い目的で使用されます。

Scrapyは、Twisted(主なライバルはTornadoです)非同期ネットワークフレームワークを使用してネットワーク通信を処理するために、ダウンロード速度を高速化することができ、独自の非同期フレームワークを実装する必要はありません、そして、様々なミドルウェアインタフェースが含まれており、柔軟に様々なニーズを満たすことができます。

ダウンロードscrapy

scrapyをインストールします。

次に、scrapyの開発プロセスです。

1、新しいプロジェクト

scrapy startproject プロジェクト名

2、新しいスパイダー -- クローラーテンプレート

まず、プロジェクトディレクトリに移動します

コマンド: scrapy genspider [pyファイルの名前] [スパイダーがクロールするURL].

ファイルの属性の意味

3, 2つの設定のconfiguration-settings.pyを変更します。

headers: scrapyダウンロードリクエストヘッダーの設定

robots プロトコル:

フルネーム: ウェブクローラ除外基準

役割: robots protocol が指定する、クロール可能な検索エンジン、クロールできないプロトコルファイル

Scrapyはデフォルトでrobotsプロトコルに従います。

4、コマンドを実行します。

scrapy クロール スパイダー名 [--nolog]

5, データを抽出

パラメータ replsonse の内容は以下の通りです:

データを抽出するメソッドでは、外部からは2つのコンテンツを抽出しません:

  • url

  • 項目

    そのため、スパイダーコンポーネント内のすべての解析メソッドは、将来的に2つの項目しか得られません:

    • url

      yield scrapy.Requests( url=url.

      	callback= ,
      	encoding = 
      )
      
    • item

      yield item

6.アイテムを書く

item.pyは以下のような構造になっています。

相対パスの使用をインポートします

7、データを保存

scrapyはspider内のアイテムを処理するためにpipelines.pyにアイテムを渡します。

パイプラインの設定

データを保存するために pipelines.py をコンパイルします。

パイプラインの原理

第四に、scrapyフレームワークダイアグラム

  • Scheduler (スケジューラ): エンジンから送信されたRequestを受け取り、一定の方法で並べ、キューに入れ、エンジンが必要とするときにエンジンに返す役割を担います。
  • Item Pipeline: スパイダーから取得したItemの処理と後処理を行います。
  • Downloader Middlewares (ダウンローダー ミドルウェア): ダウンロード機能を拡張するためにカスタマイズできるコンポーネントと考えることができます。
  • SpiderMiddlewares(スパイダーミドルウェア): エンジンとスパイダーの中間通信機能コンポーネントをカスタマイズして拡張・運用するものと考えてください。

V. Scrapyミドルウェア

はじめに: ミドルウェアは、Scrapyのコアコンセプトであり、ミドルウェアの使用は、クローラの要求で開始することができますまたは異なる状況に適応するためにクローラを開発するように、変更のカスタマイズ後のデータへの復帰を要求します。

カテゴリ: クローラミドルウェアとダウンロードミドルウェア

1、新しいpyファイルを作成します。

2、ファイル内の新しいクラス、これはメソッドを持っている必要があります:process_request()、リクエストの処理のためのprocess_requestメソッドで

3、settings.pyの設定ダウンロードミドルウェアで

ダウンロードをカスタマイズします:

from selenium import webdriver
from scrapy.http import HtmlResponse
class SleniumDownloadMiddle(object):
 def process_request(self, request, spider):
 '''
 ミドルウェアのリクエスト処理メソッドをダウンロードする
 :param request:
 :param spider:
 :return:
 '''
 #dirverinitメソッドに入れられない。
 #このサイトがseleniumを使わなければならない場合、scrapyは無視することを推奨する。
 #しかし、selniunm を使用するリクエスト数はより制限されるので、selenium の使用を検討する。
 driver = webdriver.Chrome()
 driver.get(request.url)
 driver.implicitly_wait(20)
 html_str = driver.page_source
 # - return None: continue processing this request --ダウンローダーに進む
 # - or return a Response object--カスタムダウンロード - HtmlResponse
 # - or return a Request object--プロキシを設定する
 # - or raise IgnoreRequest: process_exception() methods of---リクエストをフィルタする
 #body:レスポンスボディ
 return HtmlResponse(url=request.url,body=html_str,request=request,ecoding='utf-8')

設定コンフィギュレーションのカスタマイズ

# カスタム設定
custom_settings = CUSTOM_SETTINGS

いくつかのカスタマイズされた設定辞書でscrapyの設定を上書きすることが可能です。

import hashlib
CUSTOM_SETTINGS = {
 #robotes 
 'ROBOTSTXT_OBEY': False,
 # 
 'DEFAULT_REQUEST_HEADERS' : {
 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
 'Accept-Language': 'en',
 'X-Requested-With': 'XMLHttpRequest',
 'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.89 Safari/537.36',
 },
 #ミドルウェアをダウンロードする
 'DOWNLOADER_MIDDLEWARES' : {
 'douban_read.my_middle_wares.SleniumDownloadMiddle': 543,
 },
 #pipelines
 'ITEM_PIPELINES' :{
 'douban_read.pipelines.MongoPipeline': 300,
 },
 #データベースのURL
 'MONGO_URI' :'localhost',
 #データの名前
 'MONGO_DATABASE' :'douban_read',
}
def get_md5(value):
 return hashlib.md5(value.encode('utf-8')).hexdigest()
def update_to_mongo(db,collectionNmae,id,url,item):
 '''
 :param db: db 
 :param collectionNmae:  
 :param id: itemの更新辞書は
 :param url: idフィールドを生成する
 :param item:
 :return:
 '''
 item[id] = get_md5(item[url])
 db[collectionNmae].update({id:item[id]},{'$set':dict(item)},True)
 print(item)

scrapyはmongoに保存します。

import pymongo
from .my_settings import get_md5,update_to_mongo
class MongoPipeline(object):
 def __init__(self, mongo_uri, mongo_db):
 self.mongo_uri = mongo_uri
 self.mongo_db = mongo_db
 @classmethod
 def from_crawler(cls, crawler):
 '''
 scrapy各コンポーネントのエントリポイント
 :param crawler:
 :return:
 '''
 return cls(
 mongo_uri=crawler.settings.get('MONGO_URI'),
 mongo_db=crawler.settings.get('MONGO_DATABASE', 'items')
 )
 def open_spider(self, spider):
 self.client = pymongo.MongoClient(self.mongo_uri)
 self.db = self.client[self.mongo_db]
 def close_spider(self, spider):
 self.client.close()
 def process_item(self, item, spider):
 update_to_mongo(self.db,' ','book_id','book_url',item)
 return item

リクエストを識別するメソッド

セカンダリリクエストを送るときに、meta パラメータを使ってリクエストに印をつけることができます:

ミドルウェアでは、ダウンロードをカスタマイズしたいときに、 このパラメータを使って異なるリクエストを異なるように扱うことができます:

scrapy がプロキシを設定する方法:

VI. リストされたケース

技術のポイント

  • start_requestメソッド

     # start_urls = ['http://ww/']
     #start_urlsurlを書いてからリクエストを送信できるのは、親クラスがリクエストを開始するからである。_request() 
     #最初から始める_urls中のurlをトラバースしてリクエストを送信する。
     #start_urls親クラスの関数 start_reuqestこのメソッドは,#
     #もし_request()書き換える。,start_urlsそれでもうまくいくか?
     #もちろん、うまくいかない。
     
     def start_requests(self):
     '''
     この最初のリクエスト
     #scrapy起動後、まずアプリケーション全体が始まるurlの場所としてこのメソッドを探す。
     :return:
     '''
     yield scrapy.Request(
     		
     	)/scrapy.FormReuqst()
     
    
  • 投稿リクエストの送信: FormRequest - post オブジェクト

     yield scrapy.FormRequest(
     		url=ajax_url,
     		formdata=formdata,
     		callback=self.parse,
     		encoding='utf-8'
     		)
     
    
  • スパイダー内のデータを抽出すると、直接辞書を取得できますが、アイテムクラスと比較すると、フィールドの欠落チェックが欠けています。

  • ミドルウェアにリクエストヘッダを設定します:
Read next

フロントエンドのコード品質(1)-コメント

はじめに\n他の人に見せるためにコメントを書くことで、コードをより理解しやすくし、コードの保守性を高めることができます。これは、高いコード品質の一面でもあります。\n\n必要なければコメントをつけないでください。\nクリーンコードという本の中で、ロバート・C・マーティンはこのことについて次のように語っています。

Dec 16, 2020 · 5 min read