在 Python 脚本中使用 Scrapy Spider 输出时出现问题

2024-01-06

我想在 python 脚本中使用蜘蛛的输出。为了实现这一点,我根据另一个代码编写了以下代码thread https://stackoverflow.com/questions/40237952/get-scrapy-crawler-output-results-in-script-file-function.

我面临的问题是,函数 Spider_results() 仅一遍又一遍地返回最后一个项目的列表,而不是包含所有找到的项目的列表。当我使用 scrapy scrapy 命令手动运行同一个蜘蛛时,我得到了所需的输出。脚本的输出、手动 json 输出和蜘蛛本身如下。

我的代码有什么问题吗?

from scrapy import signals
from scrapy.crawler import CrawlerProcess
from scrapy.utils.project import get_project_settings
from circus.spiders.circus import MySpider

from scrapy.signalmanager import dispatcher


def spider_results():
    results = []

    def crawler_results(signal, sender, item, response, spider):
        results.append(item)


    dispatcher.connect(crawler_results, signal=signals.item_passed)

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


if __name__ == '__main__':
    print(spider_results())

脚本输出:

{'away_odds': 1.44,
 'away_team': 'Los Angeles Dodgers',
 'event_time': datetime.datetime(2019, 6, 8, 2, 15),
 'home_odds': 2.85,
 'home_team': 'San Francisco Giants',
 'last_update': datetime.datetime(2019, 6, 6, 20, 58, 41, 655497),
 'league': 'MLB'}, {'away_odds': 1.44,
 'away_team': 'Los Angeles Dodgers',
 'event_time': datetime.datetime(2019, 6, 8, 2, 15),
 'home_odds': 2.85,
 'home_team': 'San Francisco Giants',
 'last_update': datetime.datetime(2019, 6, 6, 20, 58, 41, 655497),
 'league': 'MLB'}, {'away_odds': 1.44,
 'away_team': 'Los Angeles Dodgers',
 'event_time': datetime.datetime(2019, 6, 8, 2, 15),
 'home_odds': 2.85,
 'home_team': 'San Francisco Giants',
 'last_update': datetime.datetime(2019, 6, 6, 20, 58, 41, 655497),
 'league': 'MLB'}]

scrapy爬行的Json输出:

[
{"home_team": "Los Angeles Angels", "away_team": "Seattle Mariners", "event_time": "2019-06-08 02:07:00", "home_odds": 1.58, "away_odds": 2.4, "last_update": "2019-06-06 20:48:16", "league": "MLB"},
{"home_team": "San Diego Padres", "away_team": "Washington Nationals", "event_time": "2019-06-08 02:10:00", "home_odds": 1.87, "away_odds": 1.97, "last_update": "2019-06-06 20:48:16", "league": "MLB"},
{"home_team": "San Francisco Giants", "away_team": "Los Angeles Dodgers", "event_time": "2019-06-08 02:15:00", "home_odds": 2.85, "away_odds": 1.44, "last_update": "2019-06-06 20:48:16", "league": "MLB"}
]

我的蜘蛛:

from scrapy.spiders import Spider
from ..items import MatchItem
import json
import datetime
import dateutil.parser

class MySpider(Spider):
    name = 'first_spider'

    start_urls = ["https://websiteXYZ.com"]

    def parse(self, response):
        item = MatchItem()

        timestamp = datetime.datetime.utcnow()

        response_json = json.loads(response.body)

        for event in response_json["el"]:
            for team in event["epl"]:
                if team["so"] == 1: item["home_team"] = team["pn"]
                if team["so"] == 2: item["away_team"] = team["pn"]

            for market in event["ml"]:
                if market["mn"] == "Match result":
                    item["event_time"] = dateutil.parser.parse(market["dd"]).replace(tzinfo=None)
                    for outcome in market["msl"]:
                        if outcome["mst"] == "1": item["home_odds"] = outcome["msp"]
                        if outcome["mst"] == "X": item["draw_odds"] = outcome["msp"]
                        if outcome["mst"] == "2": item["away_odds"] = outcome["msp"]

                if market["mn"] == 'Moneyline':
                    item["event_time"] = dateutil.parser.parse(market["dd"]).replace(tzinfo=None)
                    for outcome in market["msl"]:
                        if outcome["mst"] == "1": item["home_odds"] = outcome["msp"]
                        #if outcome["mst"] == "X": item["draw_odds"] = outcome["msp"]
                        if outcome["mst"] == "2": item["away_odds"] = outcome["msp"]


            item["last_update"] = timestamp
            item["league"] = event["scn"]

            yield item

Edit:

根据下面的答案,我尝试了以下两个脚本:

控制器.py

import json
from scrapy import signals
from scrapy.crawler import CrawlerRunner
from twisted.internet import reactor, defer
from betsson_controlled.spiders.betsson import Betsson_Spider
from scrapy.utils.project import get_project_settings


class MyCrawlerRunner(CrawlerRunner):
    def crawl(self, crawler_or_spidercls, *args, **kwargs):
        # keep all items scraped
        self.items = []

        # create crawler (Same as in base CrawlerProcess)
        crawler = self.create_crawler(crawler_or_spidercls)

        # handle each item scraped
        crawler.signals.connect(self.item_scraped, signals.item_scraped)

        # create Twisted.Deferred launching crawl
        dfd = self._crawl(crawler, *args, **kwargs)

        # add callback - when crawl is done cal return_items
        dfd.addCallback(self.return_items)
        return dfd

    def item_scraped(self, item, response, spider):
        self.items.append(item)

    def return_items(self, result):
        return self.items

def return_spider_output(output):
    return json.dumps([dict(item) for item in output])

settings = get_project_settings()
runner = MyCrawlerRunner(settings)
spider = Betsson_Spider()
deferred = runner.crawl(spider)
deferred.addCallback(return_spider_output)


reactor.run()
print(deferred)

当我执行controller.py时,我得到:

<Deferred at 0x7fb046e652b0 current result: '[{"home_team": "St. Louis Cardinals", "away_team": "Pittsburgh Pirates", "home_odds": 1.71, "away_odds": 2.19, "league": "MLB"}, {"home_team": "St. Louis Cardinals", "away_team": "Pittsburgh Pirates", "home_odds": 1.71, "away_odds": 2.19, "league": "MLB"}, {"home_team": "St. Louis Cardinals", "away_team": "Pittsburgh Pirates", "home_odds": 1.71, "away_odds": 2.19, "league": "MLB"}, {"home_team": "St. Louis Cardinals", "away_team": "Pittsburgh Pirates", "home_odds": 1.71, "away_odds": 2.19, "league": "MLB"}, {"home_team": "St. Louis Cardinals", "away_team": "Pittsburgh Pirates", "home_odds": 1.71, "away_odds": 2.19, "league": "MLB"}, {"home_team": "St. Louis Cardinals", "away_team": "Pittsburgh Pirates", "home_odds": 1.71, "away_odds": 2.19, "league": "MLB"}, {"home_team": "St. Louis Cardinals", "away_team": "Pittsburgh Pirates", "home_odds": 1.71, "away_odds": 2.19, "league": "MLB"}, {"home_team": "St. Louis Cardinals", "away_team": "Pittsburgh Pirates", "home_odds": 1.71, "away_odds": 2.19, "league": "MLB"}]'>

最近的编辑: 看完之后CrawlerProcess 与 CrawlerRunner https://stackoverflow.com/questions/39706005/crawlerprocess-vs-crawlerrunner我意识到您可能想要 CrawlerProcess。我必须使用 runner,因为我需要 klein 才能使用延迟对象。流程只需要 scrapy,而运行程序则希望与其他脚本/程序进行交互。希望这有帮助。

您需要修改 CrawlerRunner/Process 并使用信号和/或回调将项目传递到 CrawlerRunner 中的脚本中。

如何整合 Flask 和 Scrapy? https://stackoverflow.com/questions/36384286/how-to-integrate-flask-scrapy如果您查看顶部答案中的选项,则带有twisted klein 和 scrapy 的选项就是您正在寻找的示例,因为它执行相同的操作,除了在爬行后将其发送到 Klein http 服务器之外。您可以使用 CrawlerRunner 设置类似的方法,以便在脚本爬行时将每个项目发送到脚本。注意:此特定问题在收集项目后将结果发送到 Klein Web 服务器。答案是创建一个 API,它收集结果并等待抓取完成,然后将其转储为 JSON,但您可以将相同的方法应用于您的情况。主要关注的是 CrawlerRunner 如何进行子类化和扩展以添加额外的功能。

您想要做的是有一个单独的脚本来执行,该脚本导入您的 Spider 并扩展 CrawlerRunner。然后,您执行此脚本,它将启动 Twisted Reactor 并使用您的自定义运行器启动爬行过程。

也就是说,这个问题可能可以在项目管道中得到解决。创建自定义项目管道并在返回项目之前将项目传递到脚本中。

# main.py

import json
from scrapy import signals
from scrapy.crawler import CrawlerProcess
from twisted.internet import reactor, defer # import we missed
from myproject.spiders.mymodule import MySpiderName
from scrapy.utils.project import get_project_settings


class MyCrawlerProcess(CrawlerProcess):
    def crawl(self, crawler_or_spidercls, *args, **kwargs):
        # keep all items scraped
        self.items = []

        crawler = self.create_crawler(crawler_or_spidercls)

        crawler.signals.connect(self.item_scraped, signals.item_scraped)

        dfd = self._crawl(crawler, *args, **kwargs)

        dfd.addCallback(self.return_items)
        return dfd

    def item_scraped(self, item, response, spider):
        self.items.append(item)

    def return_items(self, result):
        return self.items


def return_spider_output(output):
    return json.dumps([dict(item) for item in output])


process = MyCrawlerProcess()
deferred = process.crawl(MySpider)
deferred.addCallback(return_spider_output)


process.start() - Script should block here again but I'm not sure if it will work right without using reactor.run()
print(deferred)

同样,这段代码是我未经测试的猜测。我希望它能朝着更好的方向适合你。

参考:

  • https://docs.scrapy.org/en/latest/topics/signals.html https://docs.scrapy.org/en/latest/topics/signals.html
  • https://docs.scrapy.org/en/latest/topics/practices.html?highlight=crawlerrunner https://docs.scrapy.org/en/latest/topics/practices.html?highlight=crawlerrunner
  • https://twistedmatrix.com/documents/16.2.0/core/howto/defer.html https://twistedmatrix.com/documents/16.2.0/core/howto/defer.html
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 Python 脚本中使用 Scrapy Spider 输出时出现问题 的相关文章

  • 在 Pandas 中,如何从基于另一个数据框的数据框中删除行?

    我有 2 个数据框 一个名为 USERS 另一个名为 EXCLUDE 他们都有一个名为 电子邮件 的字段 基本上 我想删除 USERS 中包含 EXCLUDE 中包含电子邮件的每一行 我该怎么做 您可以使用boolean indexing
  • TensorFlow:带有轴选项的 bincount

    在 TensorFlow 中 我可以使用 tf bincount 获取数组中每个元素的计数 x tf placeholder tf int32 None freq tf bincount x tf Session run freq feed
  • NumPy linalg.eig

    我有这个烦人的问题 但我还没有弄清楚 我有一个矩阵 我想找到特征向量 所以我写 val vec np linalg eig mymatrix 然后我得到了 vec 我的问题是 当我小组中的其他人对相同的矩阵 mymatrix 做同样的事情时
  • Python中列表中两个连续元素的平均值

    我有一个偶数个浮点数的列表 2 34 3 45 4 56 1 23 2 34 7 89 我的任务是计算 1 和 2 个元素 3 和 4 5 和 6 等元素的平均值 在 Python 中执行此操作的快捷方法是什么 data 2 34 3 45
  • CNTK 抱怨 LSTM 中的动态轴

    我正在尝试在 CNTK 中实现 LSTM 使用 Python 来对序列进行分类 Input 特征是固定长度的数字序列 时间序列 标签是 one hot 值的向量 Network input input variable input dim
  • 设置 verify_certs=False 但 elasticsearch.Elasticsearch 因证书验证失败而引发 SSL 错误

    self host KibanaProxy 自我端口 443 self user 测试 self password 测试 我需要禁止证书验证 使用选项时它与curl一起使用 k在命令行上 但是 在使用 Elasticsearch pytho
  • Python Pandas:如何对组中的所有项目进行分组并为其分配 id?

    我有 df domain orgid csyunshu com 108299 dshu com 108299 bbbdshu com 108299 cwakwakmrg com 121303 ckonkatsunet com 121303
  • 迭代列表的奇怪速度差异

    我创建了两个重复两个不同值的长列表 在第一个列表中 值交替出现 在第二个列表中 一个值出现在另一个值之前 a1 object object 10 6 a2 a1 2 a1 1 2 然后我迭代它们 不对它们执行任何操作 for in a1 p
  • Python:我不明白 sum() 的完整用法

    当然 我明白你使用 sum 与几个数字 然后它总结所有 但我正在查看它的文档 我发现了这一点 sum iterable start 第二个参数 start 的作用是什么 这太尴尬了 但我似乎无法通过谷歌找到任何示例 并且对于尝试学习该语言的
  • 为什么我应该使用 WSGI?

    使用 mod python 一段时间了 我读了越来越多关于 WSGI 有多好的文章 但没有真正理解为什么 那么我为什么要切换到它呢 有什么好处 这很难吗 学习曲线值得吗 为了用 Python 开发复杂的 Web 应用程序 您可能会使用更全面
  • `pyqt5'错误`元数据生成失败`

    我正在尝试安装pyqt5使用带有 M1 芯片和 Python 3 9 12 的 mac 操作系统 我怀疑M1芯片可能是原因 我收到一个错误metadata generation failed 最小工作示例 directly in the t
  • Django - 提交具有同一字段多个输入的表单

    预警 我对 Django 以及一般的 Web 开发 非常陌生 我使用 Django 托管一个基于 Web 的 UI 该 UI 将从简短的调查中获取用户输入 通过我用 Python 开发的一些分析来提供输入 然后在 UI 中呈现这些分析的可视
  • 使用 NLP 进行地址分割

    我目前正在开发一个项目 该项目应识别地址的每个部分 例如来自 str Jack London 121 Corvallis ARAD ap 1603 973130 输出应如下所示 street name Jack London no 121
  • 从 python 检测 macOS 中的暗模式

    我正在编写一个 PyQt 应用程序 我必须添加一个补丁 以便在启用暗模式的 Macos 上可以读取字体 app QApplication Fix for the font colours on macos when running dark
  • 附加两个具有相同列、不同顺序的数据框

    我有两个熊猫数据框 noclickDF DataFrame 0 123 321 0 1543 432 columns click id location clickDF DataFrame 1 123 421 1 1543 436 colu
  • 字符串列表,获取n个元素的公共子串,Python

    我的问题可能类似于this https stackoverflow com questions 37514193 count the number of occurrences of n length not given string in
  • 计算互相关函数?

    In R 我在用ccf or acf计算成对互相关函数 以便我可以找出哪个移位给我带来最大值 从它的外观来看 R给我一个标准化的值序列 Python 的 scipy 中是否有类似的东西 或者我应该使用fft模块 目前 我正在这样做 xcor
  • 如何使用Python保存“完整的网页”而不仅仅是基本的html

    我正在使用以下代码来使用 Python 保存网页 import urllib import sys from bs4 import BeautifulSoup url http www vodafone de privat tarife r
  • 使用 Python 将对象列表转为 JSON

    我在转换时遇到问题Object实例到 JSON ob Object list name scaping myObj base url u number page for ob in list name json string json du
  • 使用Multiprocessing和Pool时如何访问全局变量?

    我试图避免将变量冗余地传递到dataList e g 1 globalDict 2 globalDict 3 globalDict 并在全球范围内使用它们 global globalDict然而 在下面的代码中并不是这样做的解决方案 是否有

随机推荐

  • Django - 使用模板标签和“with”?

    我有一个自定义模板标签 def uploads for user user uploads Uploads objects filter uploaded by user problem upload False num uploads u
  • 基于支持向量的数据重采样器

    我正在努力实现一个数据重采样器以基于support vectors 这个想法是为了适应SVM分类器 得到support vector类的点 然后通过仅选择每个类的支持向量点附近的数据点来平衡数据 以使类具有相同数量的示例 忽略所有其他 远离
  • Google Plus API 错误gapi.loaded_0

    我尝试将 requireJS 与 Google plus API 一起使用 但是当我单击登录按钮时出现错误 这是错误和屏幕截图 GET https apis google com scs apps static js k oz gapi e
  • 如何在pytorch中使用LSTM进行分类?

    我的代码如下 class Mymodel nn Module def init self input size hidden size output size num layers batch size super Discriminato
  • 在非活动类中显示进度对话框

    我正在尝试在非活动类中显示对话框 基本上 我在我的应用程序中检测到一个对象 我想显示一个对话框 然后切换活动 我在 logcat 中收到 java lang RuntimeException 无法在未调用 Looper prepare 的线
  • 链接方法时如何返回 false

    我有一个使用方法链的验证类 我希望能够进行单次检查TRUE FALSE像这样 if obj gt checkSomething 但也有像这样的链方法 if obj gt checkSomething gt checkSomethingEls
  • 将代码转换为 R 中的函数

    我有一系列的步骤 我想将它们转换为函数 因此我只需通过调用它们即可将其应用于数据框 下面是带有一些注释的代码 library textreadr library pdftools library tidyverse library tidy
  • 函数上的模板模板参数

    这是 C 模板中的有效模板构造吗 template lt template
  • 在Qt中鼠标指针下选择Word

    当我在 QTextBrowser 中右键单击时 我需要突出显示并获取鼠标指针下的单词 我已经实施了显示上下文菜单函数为QText浏览器对于鼠标右键单击的事情 但是我无法突出显示鼠标指针下的单词并提取它 我在网上找到了如下解决方案 QText
  • 为什么这个 getchar() 循环在输入一个字符后停止?

    include
  • swig 没有名为 _example 的模块

    我无法在 Windows 上重现基本的 SWIG 示例 我的错误已在 SWIG 文档中说明 我确信我已执行他们提到的 2 个修复 对于这个错误 gt gt gt import example Traceback most recent ca
  • 编辑 php.ini 文件

    我想增加内存限制 最大输入时间 最大执行时间 in WAMP server 有 3 个php ini files 1 C wamp bin apache Apache2 4 4 bin php ini br 2 C wamp bin php
  • AngularJS:ng-bind-html 不适用于按钮标签

    我在 div ng bind html 中动态打印输入类型按钮时遇到问题 HTML 模板
  • 为什么当我更新实体框架模型时 Visual Studio 会删除我的类

    当我更新 EF 模型 版本 5 时 我遇到了一个奇怪的问题 它删除属于该模型的所有类 我的情况是这样的 我更改了两个表的键列 这两个表引用了我的主表 更新模型并未对 edmx 进行这些更改 因此我删除了这三个表 主表和两个查找表 保存了 e
  • Firebase android 无法在测试设备之外工作

    我有这个新应用程序 并添加了 Firebase Firestore 和 Cloud Firestore 用户可以使用邮箱和密码进行注册 并登录成功 然后用户可以在我的个人资料中输入生日并更新信息 问题是这样的 在模拟器中工作正常 在测试设备
  • Oracle:年份必须介于 -4713 和 +9999 之间,并且不能为 0

    我有一个像这样的 Oracle 表 EMPNO HIREDATE INDEX NUM 1 2012 11 13 1 2 2 1 3 2012 11 17 1 4 2012 11 21 1 5 2012 11 24 1 6 2013 11 2
  • Symfony 2.4 从控制器执行命令

    我想从我的控制器执行命令 fos elastica populate 我尝试了该代码 但它不起作用 我得到错误 1 var dump 显示 command fos elastica populate app new Application
  • 将 ASP.NET 菜单控件绑定到 XML

    我正在尝试将我自己的 xml 文件 出于某些特定目的 我不想使用站点地图 绑定到 ASP NET 控件 我有这段代码 在我找到的一些文章的帮助下 应该将 ASP NET 菜单控件绑定到 xml 文件 但事实并非如此 我错过了什么吗 XmlD
  • 调试器(或日志)中类似 NSDictionary 的漂亮打印

    这已经困扰我一段时间了 如何抵消在调试器中转储对象时发生的丑陋转义po foo 或通过NSLog 我尝试了多种方法来实施 description or debugDescription无济于事 鉴于这个简单的类 interface Foo
  • 在 Python 脚本中使用 Scrapy Spider 输出时出现问题

    我想在 python 脚本中使用蜘蛛的输出 为了实现这一点 我根据另一个代码编写了以下代码thread https stackoverflow com questions 40237952 get scrapy crawler output