Scrapy хранит возвращенные элементы в переменных для использования в основном скрипте

Я новичок в Scrapy и хочу попробовать следующее: извлечь некоторые значения с веб-страницы, сохранить их в переменной и использовать в моем основном скрипте. Поэтому я последовал их руководству и изменил код для своих целей:

import scrapy
from scrapy.crawler import CrawlerProcess


class QuotesSpider(scrapy.Spider):
    name = "quotes"
    start_urls = [
        'http://quotes.toscrape.com/page/1/'
    ]

    custom_settings = {
        'LOG_ENABLED': 'False',
    }

    def parse(self, response):
        global title # This would work, but there should be a better way
        title = response.css('title::text').extract_first()

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

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

print(title) # Verify if it works and do some other actions later on...

Это будет работать до сих пор, но я почти уверен, что это не очень хороший стиль или даже имеет некоторые плохие побочные эффекты, если я определяю переменную title как глобальную. Если я пропущу эту строку, то, конечно, получу ошибку «неопределенная переменная»:/ Поэтому я ищу способ вернуть переменную и использовать ее в своем основном скрипте.

Я читал о конвейере элементов, но не смог заставить его работать.

Любая помощь/идеи очень ценятся :) Заранее спасибо!


person MaGi    schedule 27.12.2017    source источник
comment
лучше используйте global - так будет проще. Трубопровод вам не поможет.   -  person furas    schedule 27.12.2017


Ответы (2)


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

Я предлагаю сохранить заголовок в файл или список и использовать его в своем основном процессе, или, если вы хотите обработать заголовок в другом скрипте, просто откройте файл и прочитайте заголовок в своем скрипте.

(Примечание: пожалуйста, игнорируйте проблему с отступом)

паук.py

import scrapy
from scrapy.crawler import CrawlerProcess

namefile = 'namefile.txt'
current_title_session = []#title stored in current session
file_append = open(namefile,'a',encoding = 'utf-8')

try:
    title_in_file = open(namefile,'r').readlines()
except:
    title_in_file = open(namefile,'w')

class QuotesSpider(scrapy.Spider):
    name = "quotes"
    start_urls = [
        'http://quotes.toscrape.com/page/1/'
    ]

    custom_settings = {
        'LOG_ENABLED': 'False',
    }

    def parse(self, response):
        title = response.css('title::text').extract_first()
        if title +'\n' not in title_in_file  and title not in current_title_session:
             file_append.write(title+'\n')
             current_title_session.append(title)
if __name__=='__main__':
    process = CrawlerProcess({
        'USER_AGENT': 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)'
    })

    process.crawl(QuotesSpider)
    process.start() # the script will block here until the crawling is finished
person Andy Wang    schedule 29.12.2017
comment
Спасибо, это устраняет проблему с оператором global, хотя я не уверен, элегантно ли создавать еще один файл для его обработки. Во всяком случае - это работает нормально для меня :-) - person MaGi; 01.01.2018

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

На самом деле я бы рекомендовал использовать другой сервис для связи между процессами, что-то вроде Redis, чтобы не возникало конфликтов между ваш паук и любой другой процесс.

Его очень просто настроить и использовать, в документации есть очень простой пример.

Создайте соединение Redis внутри паука и снова в основном процессе (думайте о них как о отдельных процессах). Паук устанавливает переменные, а основной процесс считывает (или gets) информацию.

person eLRuLL    schedule 27.12.2017
comment
Спасибо, на короткое время я выберу ответ Фураса и ЭндиВанга, но если у меня будет время, я прочитаю Redis :) - person MaGi; 01.01.2018