Магазин 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 как глобальную. Если я пропущу эту строку, то получу ошибку "неопределенная переменная", конечно:/ Поэтому я ищу способ вернуть переменную и использовать ее в своем основном скрипте.
Я читал о конвейере предметов, но не смог заставить его работать.
Любая помощь / идеи высоко ценятся:) Заранее спасибо!
2 ответа
С помощью global
как вы знаете, это не очень хороший стиль, особенно если вам нужно расширить спрос.
Я предлагаю сохранить заголовок в файл или список и использовать его в вашем основном процессе, или, если вы хотите обработать заголовок в другом скрипте, просто откройте файл и прочитайте заголовок в вашем скрипте.
(Примечание: пожалуйста, игнорируйте проблему с отступами)
spider.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
Делая переменную global
должен работать на то, что вам нужно, но, как вы упомянули, это не очень хороший стиль.
На самом деле я бы порекомендовал использовать другой сервис для связи между процессами, например Redis, чтобы у вас не возникало конфликтов между вашим пауком и любым другим процессом.
Он очень прост в настройке и использовании, в документации приведен очень простой пример.
Создайте соединение redis внутри паука и снова о главном процессе (подумайте о них как об отдельных процессах). Паук устанавливает переменные, и основной процесс читает (или get
с) информация.