【问题标题】:How to set default settings for running scrapy as a python script?如何设置将scrapy作为python脚本运行的默认设置?
【发布时间】:2016-11-18 09:17:16
【问题描述】:

我想将 scrapy 作为 python 脚本运行,但我不知道如何正确设置设置或如何提供它们。我不确定这是否是设置问题,但我认为是。

我的配置:

  • Python 2.7 x86(作为虚拟环境)
  • Scrapy 1.2.1
  • Win 7 x64

我接受了https://doc.scrapy.org/en/latest/topics/practices.html#run-scrapy-from-a-script 的建议,让它运行起来。我对以下建议有一些疑问:

如果您在 Scrapy 项目中,则可以使用一些额外的帮助程序在项目中导入这些组件。您可以自动导入您的蜘蛛并将它们的名称传递给 CrawlerProcess,并使用 get_project_settings 获取带有您项目设置的 Settings 实例。

那么“在 Scrapy 项目中”是什么意思?当然我必须导入库并安装依赖项,但我想避免使用scrapy crawl xyz 开始爬取过程。

这是 myScrapy.py 的代码

from scrapy.crawler import CrawlerProcess
from scrapy.utils.project import get_project_settings
from scrapy.spiders import CrawlSpider, Rule
from scrapy.linkextractors import LinkExtractor
from scrapy.item import Item, Field
import os, argparse


#Initialization of directories
projectDir = os.path.dirname(os.path.realpath('__file__'))
generalOutputDir = os.path.join(projectDir, 'output')

parser = argparse.ArgumentParser()
parser.add_argument("url", help="The url which you want to scan", type=str)
args = parser.parse_args()
urlToScan = args.url

#Stripping of given URL to get only the host + TLD
if "https" in urlToScan:
    urlToScanNoProt = urlToScan.replace("https://","")
    print "used protocol: https"
if "http" in urlToScan:
    urlToScanNoProt = urlToScan.replace("http://","")
    print "used protocol: http"

class myItem(Item):
    url = Field()

class mySpider(CrawlSpider):
    name = "linkspider"
    allowed_domains = [urlToScanNoProt]
    start_urls = [urlToScan,]
    rules = (Rule(LinkExtractor(), callback='parse_url', follow=True), )

    def generateDirs(self):
        if not os.path.exists(generalOutputDir):
            os.makedirs(generalOutputDir)
        specificOutputDir = os.path.join(generalOutputDir, urlToScanNoProt)
        if not os.path.exists(specificOutputDir):
            os.makedirs(specificOutputDir)
        return specificOutputDir

    def parse_url(self, response):
        for link in LinkExtractor().extract_links(response):
            item = myItem()
            item['url'] = response.url
        specificOutputDir = self.generateDirs()
        filename = os.path.join(specificOutputDir, response.url.split("/")[-2] + ".html")
        with open(filename, "wb") as f:
            f.write(response.body)
        return CrawlSpider.parse(self, response)
        return item

process = CrawlerProcess(get_project_settings())
process.crawl(mySpider)
process.start() # the script will block here until the crawling is finished

为什么我必须打电话给process.crawl(mySpider) 而不是process.crawl(linkspider)?我认为获取设置是一个问题,因为它们是在“正常”scrapy-project(你必须在其中运行scrapy crawl xyz)中设置的,因为putput说 2016-11-18 10:38:42 [scrapy] INFO: Overridden settings: {} 我希望你能理解我的问题(英语不是我的母语……;)) 提前致谢!

【问题讨论】:

    标签: python python-2.7 scrapy scrapy-spider


    【解决方案1】:

    当使用脚本(而不是 scrapy crawl)运行爬网时,其中一个选项确实是使用 CrawlerProcess

    那么“在 Scrapy 项目中”是什么意思?

    这意味着如果您在使用scrapy startproject 创建的scrapy 项目的根目录运行脚本,即您拥有scrapy.cfg 文件和[settings] 部分等。

    为什么我必须调用 process.crawl(mySpider) 而不是 process.crawl(linkspider)?

    阅读the documentation on scrapy.crawler.CrawlerProcess.crawl() for details

    参数:
    crawler_or_spidercls(Crawler 实例、Spider 子类或字符串)- 已经创建的爬虫,或者是一个蜘蛛类或项目中的蜘蛛名称来创建它

    我不知道框架的那一部分,但我怀疑只是蜘蛛名称 - 我相信你的意思是 而不是 process.crawl("linkspider") ,并且在一个scrapy项目之外,scrapy 确实不知道在哪里寻找蜘蛛(它没有提示)。因此,要告诉 scrapy 运行哪个蜘蛛,不妨直接给出类(而不是蜘蛛类的实例)。

    get_project_settings() 是一个助手,但本质上,CrawlerProcess 需要使用 Settings 对象进行初始化(请参阅https://docs.scrapy.org/en/latest/topics/api.html#scrapy.crawler.CrawlerProcess

    其实它也接受一个设置dict(也就是internally converted into a Settings instance),如the example you linked to所示:

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

    因此,根据与 scrapy 默认设置相比,您需要覆盖哪些设置,您需要执行以下操作:

    process = CrawlerProcess({
        'SOME_SETTING_KEY': somevalue,
        'SOME_OTHERSETTING_KEY': someothervalue,
        ...
    })
    process.crawl(mySpider)
    ...
    

    【讨论】:

    • 感谢您的回答!我将尝试在一个 scrapy 项目中使用 get_project_settings() 运行我的脚本
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-29
    • 2014-08-29
    • 2020-10-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多