以上の爬虫類、ベースケースと[爬虫類] scrapy動的構成プロセス

       我々はニュース、複数のサイトをクロールし、それはテーブルとデータベースに格納されます希望のような、複数のサイトから必要なデータを取るために登るする必要がある場合があります。私たちは蜘蛛のクラスを定義し、各サイトにアクセスする必要がありますするつもりですか?実際には、あなたは、私たちが動的に追加またはそれから、複数のウェブサイトのクロールを達成することができ、プログラムコードを変更する必要がテーブルまたはルールの設定ルールの設定ファイルを保持しないことで、クロールルールを変更することができますする必要はありません。

       これを行うために、我々はもはやフロント使用することができscrapy crawl test、このコマンドのを、私たちは、プログラムScrapy SPIDを実行する必要がありません

       これは、使用scrapyの提供できるコアAPIの代わりに伝統的で、プログラム的に開始scrapyをscrapy crawl起動モード。あなたはツイスト原子炉内部を実行する必要があるので、Scrapy非同期ネットワークフレームワークは、土台ツイストの上に構築されました。まず、あなたが使用することができscrapy.crawler.CrawlerProcess、あなたのクモを実行するには、このクラスを、このクラスはあなたのためのツイスト原子炉を起動し、ログおよびシャットダウンプロセッサを構成することができます。すべてのscrapyコマンドは、このクラスを使用します

        まず、コードの変更main.pyファイルには、次のコードを使用し、excuteすることはできません。

import scrapy
from scrapy.crawler import CrawlerProcess
from scrapy.utils.project import get_project_settings
process = CrawlerProcess(get_project_settings())
process.crawl('maoyan')#爬虫名称
process.crawl('maoyan2')#爬虫名称
process.start() # the script will block here until the crawling is finished

         クロールのソースコードを修正し、テストの過程で私たちを送って、設定をマーク。

         まず、同じディレクトリitem.py、という名前のMycmdにフォルダを作成します。第二に、ファイル__init__.py、mycrawl.pyファイルがあるフォルダ内のNULL値を確立し、それに下のコードをコピーします。そしてbasicdemoがプロジェクト名である、のMycmdフォルダ名であるsetting.pyファイル、内COMMANDS_MODULE =「basicdemo.mycmd」

import os
from scrapy.commands import ScrapyCommand
from scrapy.utils.conf import arglist_to_dict
from scrapy.utils.python import without_none_values
from scrapy.exceptions import UsageError


class Command(ScrapyCommand):

    requires_project = True

    def syntax(self):
        return "[options] <spider>"

    def short_desc(self):
        return "Run a spider"

    def add_options(self, parser):
        ScrapyCommand.add_options(self, parser)
        parser.add_option("-a", dest="spargs", action="append", default=[], metavar="NAME=VALUE",
                          help="set spider argument (may be repeated)")
        parser.add_option("-o", "--output", metavar="FILE",
                          help="dump scraped items into FILE (use - for stdout)")
        parser.add_option("-t", "--output-format", metavar="FORMAT",
                          help="format to use for dumping items with -o")

    def process_options(self, args, opts):
        ScrapyCommand.process_options(self, args, opts)
        try:
            opts.spargs = arglist_to_dict(opts.spargs)
        except ValueError:
            raise UsageError("Invalid -a value, use -a NAME=VALUE", print_help=False)
        if opts.output:
            if opts.output == '-':
                self.settings.set('FEED_URI', 'stdout:', priority='cmdline')
            else:
                self.settings.set('FEED_URI', opts.output, priority='cmdline')
            feed_exporters = without_none_values(
                self.settings.getwithbase('FEED_EXPORTERS'))
            valid_output_formats = feed_exporters.keys()
            if not opts.output_format:
                opts.output_format = os.path.splitext(opts.output)[1].replace(".", "")
            if opts.output_format not in valid_output_formats:
                raise UsageError("Unrecognized output format '%s', set one"
                                 " using the '-t' switch or as a file extension"
                                 " from the supported list %s" % (opts.output_format,
                                                                  tuple(valid_output_formats)))
            self.settings.set('FEED_FORMAT', opts.output_format, priority='cmdline')

    def run(self, args, opts):
        # 获取爬虫列表
        spd_loader_list = self.crawler_process.spider_loader.list()
        # 遍历各爬虫
        for spname in spd_loader_list or args:
            self.crawler_process.crawl(spname, **opts.spargs)
            print("此时启动的爬虫:" + spname)
        self.crawler_process.start()

セットitem.pyファイル

from scrapy.loader import ItemLoader
from scrapy.loader.processors import TakeFirst, MapCompose, Join
import scrapy
class BasicdemoItem(scrapy.Item):
    title=scrapy.Field()
    article=scrapy.Field(
        default_output_processor=TakeFirst()
    )
class BasicdemoItem2(scrapy.Item):
    name=scrapy.Field()
    price=scrapy.Field()

設定された2つのクローラパイプファイル文書は、ここでは非同期メモリ・データベースである、(ここではない十分な経験が、後者はより多くの労力を結合することができない2つだけのパイプファイルをされてしまいました)

パイプファイルの.py

import pymysql
# 使用twsited异步IO框架,实现数据的异步写入。
from pymysql import cursors
from twisted.enterprise import adbapi
class Basicdemo2Pipeline(object):
    def __init__(self):
        dbparams = {
            'host': 'localhost',
            'port': 3306,
            'user': 'root',
            'password': '',
            'database': 'test1',
            'charset': 'utf8',
            'cursorclass': cursors.DictCursor  # 指定cursor的类
        }
        self.db_pool = adbapi.ConnectionPool('pymysql', **dbparams)
        self._sql = None

    @property
    def sql(self):
        if not self._sql:
            self._sql = 'INSERT INTO boods(dd,ff) VALUES(%s,%s)'
            return self._sql
        return self._sql

    def process_item(self, item, spider):
        query = self.db_pool.runInteraction(self.insert_db,item)
        query.addErrback(self.handle_error, item, spider)
    def insert_db(self,cursor, item):
        for i in range(len(item['name'])) :
            values = (
                item['name'][i],
                item['price'][i],
            )
            print("Insert 成功了")
            cursor.execute(self.sql, values)
    def handle_error(self,error,item,spider):
        print('='*10 + "error" + '='*10)
        print(error)
        print('=' * 10 + "error" + '=' * 10)

class Basicdemo1Pipeline(object):
    def __init__(self):
        dbparams = {
            'host': 'localhost',
            'port': 3306,
            'user': 'root',
            'password': '',
            'database': 'test1',
            'charset': 'utf8',
            'cursorclass': cursors.DictCursor  # 指定cursor的类
        }
        self.db_pool = adbapi.ConnectionPool('pymysql', **dbparams)
        self._sql = None

    @property
    def sql(self):
        if not self._sql:
            self._sql = 'INSERT INTO boods(dd,ff) VALUES(%s,%s)'
            return self._sql
        return self._sql

    def process_item(self, item, spider):
        query = self.db_pool.runInteraction(self.insert_db,item)
        query.addErrback(self.handle_error, item, spider)
    def insert_db(self,cursor, item):
        for i in range(len(item['title'])) :
            values = (
                item['title'][i],
                item['article'][i],
            )
            print("Insert 成功了")
            cursor.execute(self.sql, values)
    def handle_error(self,error,item,spider):
        print('='*10 + "error" + '='*10)
        print(error)
        print('=' * 10 + "error" + '=' * 10)

提供setting.pyファイル(ここでは、フロントCMDを追加するコードが含まれています)

# -*- coding: utf-8 -*-

# Scrapy settings for basicdemo project
#
# For simplicity, this file contains only settings considered important or
# commonly used. You can find more settings consulting the documentation:
#
#     https://docs.scrapy.org/en/latest/topics/settings.html
#     https://docs.scrapy.org/en/latest/topics/downloader-middleware.html
#     https://docs.scrapy.org/en/latest/topics/spider-middleware.html

BOT_NAME = 'basicdemo'

SPIDER_MODULES = ['basicdemo.spiders']
NEWSPIDER_MODULE = 'basicdemo.spiders'
COMMANDS_MODULE = 'basicdemo.mycmd'

ROBOTSTXT_OBEY = True

ITEM_PIPELINES = {
    'basicdemo.pipelines.Basicdemo1Pipeline': 100,
    'basicdemo.pipelines.Basicdemo2Pipeline': 100,
}
LOG_LEVEL = 'ERROR'

二つのクラスのアイテムはitem.pyで提供されます

from scrapy.loader import ItemLoader
from scrapy.loader.processors import TakeFirst, MapCompose, Join
import scrapy
class BasicdemoItem(scrapy.Item):
    title=scrapy.Field()
    article=scrapy.Field(
        default_output_processor=TakeFirst()
    )
class BasicdemoItem2(scrapy.Item):
    name=scrapy.Field()
    price=scrapy.Field()

各ファイルのクローラに次のコードを追加の.py

   custom_settings = {
        'ITEM_PIPELINES': {'basicdemo.pipelines.Basicdemo2Pipeline': 100},
    }
次のように具体的な例としては、以下のとおりです。
import scrapy
from scrapy.loader import ItemLoader
from basicdemo.items import BasicdemoItem2
class Maoyan2Spider(scrapy.Spider):
    name = 'maoyan2'
    #allowed_domains = ['www.yub2b.com/mall/']
    start_urls = ['http://www.yub2b.com/mall/']
    custom_settings = {
        'ITEM_PIPELINES': {'basicdemo.pipelines.Basicdemo2Pipeline': 100},
    }
    def parse(self, response):
        dl = response.css('.box_body .mthumb table tr td ul li a')
        item1Loader = ItemLoader(item=BasicdemoItem2(), response=response)
        item1Loader.add_css('name', '.box_body .mthumb table tr td ul li a::text')
        item1Loader.add_css('price', '.box_body .mthumb table tr td ul li span::text')
        print("输出在这里,爬虫1")
        yield item1Loader.load_item()

ここでは同じ2つのクローラプロセスで使用可能な2つのクラスがあります。

最初でCrawlerProcessは、次のコードmain.pyファイルを追加します。

from scrapy.crawler import CrawlerProcess
from scrapy.utils.project import get_project_settings

process = CrawlerProcess(get_project_settings())

# myspd1是爬虫名
process.crawl('maoyan')
process.crawl('maoyan2')

process.start()

第二のクラスであるCrawlerRunnerは、次のコードmain.pyファイルを追加します。

import scrapy
from twisted.internet import reactor
from scrapy.crawler import CrawlerRunner
from scrapy.utils.log import configure_logging
from scrapy.utils.project import get_project_settings
runner = CrawlerRunner(get_project_settings())
# myspd1是爬虫名
runner.crawl('maoyan')
runner.crawl('maoyan2')
d = runner.join()
d.addBoth(lambda _: reactor.stop())
reactor.run()

 

公開された56元の記事 ウォンの賞賛2 ビュー30000 +

おすすめ

転載: blog.csdn.net/fan13938409755/article/details/105005046