Подтвердить что ты не робот

Как запустить Scrapy из Python script

Я новичок в Scrapy, и я ищу способ запустить его с Python script. Я нашел 2 источника, которые объясняют это:

http://tryolabs.com/Blog/2011/09/27/calling-scrapy-python-script/

http://snipplr.com/view/67006/using-scrapy-from-a-script/

Я не могу понять, где я должен поставить свой код паука и как его вызвать из основной функции. Пожалуйста помоги. Это пример кода:

# This snippet can be used to run scrapy spiders independent of scrapyd or the scrapy command line tool and use it from a script. 
# 
# The multiprocessing library is used in order to work around a bug in Twisted, in which you cannot restart an already running reactor or in this case a scrapy instance.
# 
# [Here](http://groups.google.com/group/scrapy-users/browse_thread/thread/f332fc5b749d401a) is the mailing-list discussion for this snippet. 

#!/usr/bin/python
import os
os.environ.setdefault('SCRAPY_SETTINGS_MODULE', 'project.settings') #Must be at the top before other imports

from scrapy import log, signals, project
from scrapy.xlib.pydispatch import dispatcher
from scrapy.conf import settings
from scrapy.crawler import CrawlerProcess
from multiprocessing import Process, Queue

class CrawlerScript():

    def __init__(self):
        self.crawler = CrawlerProcess(settings)
        if not hasattr(project, 'crawler'):
            self.crawler.install()
        self.crawler.configure()
        self.items = []
        dispatcher.connect(self._item_passed, signals.item_passed)

    def _item_passed(self, item):
        self.items.append(item)

    def _crawl(self, queue, spider_name):
        spider = self.crawler.spiders.create(spider_name)
        if spider:
            self.crawler.queue.append_spider(spider)
        self.crawler.start()
        self.crawler.stop()
        queue.put(self.items)

    def crawl(self, spider):
        queue = Queue()
        p = Process(target=self._crawl, args=(queue, spider,))
        p.start()
        p.join()
        return queue.get(True)

# Usage
if __name__ == "__main__":
    log.start()

    """
    This example runs spider1 and then spider2 three times. 
    """
    items = list()
    crawler = CrawlerScript()
    items.append(crawler.crawl('spider1'))
    for i in range(3):
        items.append(crawler.crawl('spider2'))
    print items

# Snippet imported from snippets.scrapy.org (which no longer works)
# author: joehillen
# date  : Oct 24, 2010

Спасибо.

4b9b3361

Ответ 1

Все остальные ответы ссылаются на Scrapy v0.x. Согласно обновленным документам, Scrapy 1.0 требует:

import scrapy
from scrapy.crawler import CrawlerProcess

class MySpider(scrapy.Spider):
    # Your spider definition
    ...

process = CrawlerProcess({
    'USER_AGENT': 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)'
})

process.crawl(MySpider)
process.start() # the script will block here until the crawling is finished

Ответ 2

Хотя я не пробовал, я думаю, что ответ можно найти в документации по скрипам. Цитировать прямо из него:

from twisted.internet import reactor
from scrapy.crawler import Crawler
from scrapy.settings import Settings
from scrapy import log
from testspiders.spiders.followall import FollowAllSpider

spider = FollowAllSpider(domain='scrapinghub.com')
crawler = Crawler(Settings())
crawler.configure()
crawler.crawl(spider)
crawler.start()
log.start()
reactor.run() # the script will block here

Из того, что я собираю, это новая разработка в библиотеке, которая делает некоторые из ранних подходов онлайн (например, в вопросе) устаревшими.

Ответ 3

В scrapy 0.19.x вы должны это сделать:

from twisted.internet import reactor
from scrapy.crawler import Crawler
from scrapy import log, signals
from testspiders.spiders.followall import FollowAllSpider
from scrapy.utils.project import get_project_settings

spider = FollowAllSpider(domain='scrapinghub.com')
settings = get_project_settings()
crawler = Crawler(settings)
crawler.signals.connect(reactor.stop, signal=signals.spider_closed)
crawler.configure()
crawler.crawl(spider)
crawler.start()
log.start()
reactor.run() # the script will block here until the spider_closed signal was sent

Обратите внимание на следующие строки

settings = get_project_settings()
crawler = Crawler(settings)

Без этого ваш паук не будет использовать ваши настройки и не сохранит элементы. Понадобился время, чтобы понять, почему пример в документации не сохранял мои предметы. Я отправил запрос на перенос, чтобы исправить пример документа.

Еще один способ сделать это - просто вызвать команду непосредственно от вас script

from scrapy import cmdline
cmdline.execute("scrapy crawl followall".split())  #followall is the spider name

Скопировал этот ответ из моего первого ответа здесь: fooobar.com/questions/159937/...

Ответ 4

Когда в одном питоне script необходимо запустить несколько сканеров, остановка реактора должна выполняться с осторожностью, поскольку реактор может быть остановлен только один раз и не может быть перезапущен.

Тем не менее, я обнаружил, что, выполняя свой проект, используя

os.system("scrapy crawl yourspider")

является самым простым. Это избавит меня от обработки всех видов сигналов, особенно когда у меня есть несколько пауков.

Если производительность является проблемой, вы можете использовать многопроцессорную обработку для запуска ваших пауков параллельно, например:

def _crawl(spider_name=None):
    if spider_name:
        os.system('scrapy crawl %s' % spider_name)
    return None

def run_crawler():

    spider_names = ['spider1', 'spider2', 'spider2']

    pool = Pool(processes=len(spider_names))
    pool.map(_crawl, spider_names)

Ответ 5

@Фэн Привет Фэн,

Вы пытались использовать _thread для запуска os.system('scrapy crawl %s' % spider_name)?

Я пытался использовать многопоточность для запуска разных пауков, но я получил разные результаты на Windows и Mac OS.

Ответ 6

# -*- coding: utf-8 -*-
import sys
from scrapy.cmdline import execute


def gen_argv(s):
    sys.argv = s.split()


if __name__ == '__main__':
    gen_argv('scrapy crawl abc_spider')
    execute()

Поместите этот код в путь, из которого вы можете запустить scrapy crawl abc_spider из командной строки. (Протестировано с помощью Scrapy == 0.24.6)

Ответ 7

Если вы хотите запустить простой обход, легко выполнить только команду:

сканирование. Существуют и другие варианты экспорта ваших результатов для хранения в некоторых форматах, таких как: Json, xml, csv.

scrapy crawl -o result.csv или result.json или result.xml.

вы можете попробовать.