4

我对 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 变量定义为全局变量,甚至会产生一些不好的副作用。如果我跳过该行,那么我当然会得到“未定义的变量”错误:/因此我正在寻找一种方法来返回变量并在我的主脚本中使用它。

我已阅读有关项目管道的信息,但无法使其工作。

任何帮助/想法都非常感谢:)在此先感谢!

4

2 回答 2

3

制作变量global应该可以满足您的需要,但是正如您所提到的,它的风格不好。

我实际上建议使用不同的服务来进行进程之间的通信,比如Redis,这样你的蜘蛛和任何其他进程之间就不会发生冲突。

设置和使用非常简单,文档中有一个非常简单的示例

在蜘蛛内部实例化 redis 连接,然后在主进程上再次实例化(将它们视为单独的进程)。蜘蛛设置变量,主进程读取(或get)信息。

于 2017-12-27T14:46:31.470 回答
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
于 2017-12-29T03:55:54.783 回答