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