从脚本运行Scrapy爬虫

24

1
可能你将那段代码放在了你想要运行蜘蛛的脚本中。 - Talvalin
@Talvalin 我在问应该把脚本放在哪里? - Marco Dinatsoli
1
如果您的系统路径和PYTHONPATH设置正确,您应该能够将脚本放在任何您喜欢的地方。 - Talvalin
@Talvalin,那么我的Scrapy项目也应该在PythonPath中吗?如果是的话。假设我有5个项目要爬取这个域名xxx.com,如果所有蜘蛛的名称都相同但在不同的项目中,哪一个会被触发?我实际上有这种情况。 - Marco Dinatsoli
可能是如何在Python脚本中运行Scrapy的重复问题。 - Trilarion
显示剩余2条评论
4个回答

41

很简单明了 :)

只需查看 官方文档。我会做一点更改,这样您就可以控制蜘蛛仅在执行 python myscript.py 时才运行,而不是每次从脚本中导入时都运行。只需添加一个 if __name__ == "__main__"

import scrapy
from scrapy.crawler import CrawlerProcess

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

if __name__ == "__main__":
    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

现在将文件保存为myscript.py,并运行`python myscript.py`。

享受吧!


1
我已经完成了你的代码。那么,如何将输出保存到JSON文件中呢?如果我们从命令提示符或终端运行scrapy,我们可以设置scrapy crawl MySpider -o output.json,然后我们就可以得到输出的JSON文件。如果我们使用你的代码,我应该在哪里放置代码以将输出保存到JSON文件中呢?@AlmogCohen - syaifulhusein
@syaifulhusein 是的,这更加复杂。我在我的一个项目中做了以下事情:我创建了一个Scrapy管道,将处理后的项存储在内存中。然后在蜘蛛运行结束时,我从内存存储中取出它们,并按照自己的意愿操作这些项。如果愿意开一个新问题,我可以在那里回答并提供代码示例。 - Almog Cohen
+Almog Cohen,我认为你的代码示例是解决我在https://stackoverflow.com/questions/52141729/get-scrapy-result-inside-a-django-view中问题的答案。能否在那里回答一下?谢谢。 - Paulo Fabrício
@PaulozOiOzuLLuFabrício,你懂的。看看我的回答吧。 syaifulhusein,如果你仍然需要问题的答案,你也可以去那里。https://stackoverflow.com/questions/52141729/get-scrapy-result-inside-a-django-view - Almog Cohen
非常优雅的解决方案。 - WJA
@syaifulhusein 你可以通过为蜘蛛指定自定义设置来添加输出位置,settings = {"FEED_FORMAT": "json", "FEED_URI": "/tmp/verizon.json"} crawler_process = CrawlerProcess(settings=settings) - learnToCode

6

为什么不直接这样做呢?

from scrapy import cmdline

cmdline.execute("scrapy crawl myspider".split())

将该脚本放在与 scrapy.cfg 相同的路径下。

6

幸运的是,Scrapy源代码是开放的,所以您可以按照抓取命令的方式进行操作,并在您的代码中执行相同的操作:

...
crawler = self.crawler_process.create_crawler()
spider = crawler.spiders.create(spname, **opts.spargs)
crawler.crawl(spider)
self.crawler_process.start()

2
**opts.spargs 是什么? - Yuda Prawira

3
你可以创建一个普通的Python脚本,然后使用Scrapy的命令行选项runspider,这使得你可以在不必创建项目的情况下运行爬虫。
例如,你可以创建一个名为stackoverflow_spider.py的单个文件,并添加如下内容:
import scrapy

class QuestionItem(scrapy.item.Item):
    idx = scrapy.item.Field()
    title = scrapy.item.Field()

class StackoverflowSpider(scrapy.spider.Spider):
    name = 'SO'
    start_urls = ['http://stackoverflow.com']
    def parse(self, response):
        sel = scrapy.selector.Selector(response)
        questions = sel.css('#question-mini-list .question-summary')
        for i, elem in enumerate(questions):
            l = scrapy.contrib.loader.ItemLoader(QuestionItem(), elem)
            l.add_value('idx', i)
            l.add_xpath('title', ".//h3/a/text()")
            yield l.load_item()

假设您已经正确安装了Scrapy,您可以使用以下命令运行它:

scrapy runspider stackoverflow_spider.py -t json -o questions-items.json

我在这一行代码 l = scrapy.contrib.loader.ItemLoader(QuestionItem(), elem) 上遇到了错误:exceptions.AttributeError: 'module' object has no attribute 'loader'。你有什么解决办法吗? - Basj
@Basj 你需要导入scrapy.contrib.loader才能使其工作。 - Elias Dorneles
谢谢@elias。我应该在你的代码中添加什么,才能够从python stackoverflow_spider.py运行它,而不是使用scrapy runspider ...?我真的被这个小问题卡住了。 - Basj
由于Scrapy是在Twisted之上工作的方式,因此这不是推荐使用它的方式:通常您使用scrapy命令运行蜘蛛,或将项目部署在scrapyd实例上。如果您真的想在脚本中运行,我无法为您提供比那些文档更多的信息--我个人从未这样做过。 - Elias Dorneles

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接