关于Flask框架中启动Scrapy爬虫框架时的几种问题的解决

2023-11-13

最近开发的爬虫调度系统是由Flask框架提供接口,在Flask中启动Scrapy项目,开发期间遇到了几个问题,网上找找,自己也琢磨了好久,终于顺利解决。问题如下:

一、Scrapy、crawl指令找不到

问题描述:

先看一下我的项目结构,如下:

hydra是Flask项目目录,medical_illness下是Scrapy项目,handler_scrpy是接口文件。

现在要做的就是接口文件收到指令,然后启动scrapy项目,在scrapy项目下的main_illess.py文件是启动spider的,我在接口文件引入了这个文件,然后去运行它,就会报如上错误

Scrapy 1.7.1 - no active project 

Unknown command: crawl Use "scrapy" to see

解决思路:

这是因为,在handler_scrpy中启动main_illess.py时当前工作目录是在Flask项目下:

D:\文档\个人\项目\hydra

并不在scrapy项目目录下,所以报了如上错误。在main_illess.py中做如下修改:

import os
from scrapy import cmdline
from filter.filter_change_path import set_new_path
from .disease import spiders


def start_crawl(spider_name):
    b = 'scrapy crawl '
    c = b + spider_name

    # 获取spiders文件所在的目录,并将工作目录切换到spider所在目录下
    set_new_path(os.path.dirname(spiders.__file__))

    cmdline.execute(c.split())

切换后的工作空间:

D:\文档\个人\项目\hydra\spiders\spider_script\medical_illness\disease\disease\spiders

重点是注释部分,获得导入的spidres所在目录(即scrapy所在目录),然后见工作空间切换到scrapy目录,然后最后一句执行爬虫,启动完爬虫以后需要将工作目录再切换回去(为什么要用到进程,在第二个问题中会讲到):

# 启动scrapy项目文件
def start_crawler_threads(topic_name, rules, start_url):
    # 通过start_url得到spider名字
    spider_name = get_spider(start_url)

    # 获得当前工作目录(根目录)
    old_path = os.getcwd()

    # 在进程中启动爬虫
    crawl_threads = Process(target=main_illness.start_crawl, args=(spider_name ,))
    crawl_threads.start()

    # 启动完线程以后交给工作目录还原
    set_old_path(old_path)

 

set_old_path()、set_new_path()方法所在文件定义如下:

import os

"""
更改与还原工作目录
"""


def set_new_path(path):
    os.chdir(path)


def set_old_path(path):
    os.chdir(path)

到此就解决找不到scrapy和crawl的问题了。

二、ValueError: signal only works in main thread

ERROR:tornado.application:Exception in callback (<zmq.sugar.socket.Socket object at 0x7f44c4d698d0>, <function wrap.<locals>.null_wrapper at 0x7f44c4d02378>)
Traceback (most recent call last):
  File "/mnt/home2/zxm/anaconda3/lib/python3.6/site-packages/tornado/ioloop.py", line 888, in start
    handler_func(fd_obj, events)
  File "/mnt/home2/zxm/anaconda3/lib/python3.6/site-packages/tornado/stack_context.py", line 277, in null_wrapper
    return fn(*args, **kwargs)
  File "/mnt/home2/zxm/anaconda3/lib/python3.6/site-packages/zmq/eventloop/zmqstream.py", line 450, in _handle_events
    self._handle_recv()
  File "/mnt/home2/zxm/anaconda3/lib/python3.6/site-packages/zmq/eventloop/zmqstream.py", line 480, in _handle_recv
    self._run_callback(callback, msg)
  File "/mnt/home2/zxm/anaconda3/lib/python3.6/site-packages/zmq/eventloop/zmqstream.py", line 432, in _run_callback
    callback(*args, **kwargs)
  File "/mnt/home2/zxm/anaconda3/lib/python3.6/site-packages/tornado/stack_context.py", line 277, in null_wrapper
    return fn(*args, **kwargs)
  File "/mnt/home2/zxm/anaconda3/lib/python3.6/site-packages/ipykernel/kernelbase.py", line 283, in dispatcher
    return self.dispatch_shell(stream, msg)
  File "/mnt/home2/zxm/anaconda3/lib/python3.6/site-packages/ipykernel/kernelbase.py", line 233, in dispatch_shell
    self.pre_handler_hook()
  File "/mnt/home2/zxm/anaconda3/lib/python3.6/site-packages/ipykernel/kernelbase.py", line 248, in pre_handler_hook
    self.saved_sigint_handler = signal(SIGINT, default_int_handler)
  File "/mnt/home2/zxm/anaconda3/lib/python3.6/signal.py", line 47, in signal
    handler = _signal.signal(_enum_to_int(signalnum), _enum_to_int(handler))
ValueError: signal only works in main thread

问题描述:

在我成功解决工作空间的问题之后这个问题就紧接着来了,导致以上错误的几个原因,我google了一下,网上也有反映这个错误的,但是按照他们的方法并不能解决我的问题,于是根据这个错误提示,大胆猜测——

解决思路:

“signal仅适用于主线程”,是不是因为在Flask中起动scrapy爬虫,请求flask的接口已经占用了主线程并且阻塞等待爬虫运行,所以再启动Scrapy时就会报ValueError: signal only works in main thread

根据这个思路,再启动Scrapy时,创建一个新的进程,让Scrapy在此进程中的主线程中运行,如下:

# 启动scrapy项目文件
def start_crawler_threads(topic_name, rules, start_url):
    # 通过start_url得到spider名字
    spider_name = get_spider(start_url)

    # 获得当前工作目录(根目录)
    old_path = os.getcwd()

    # 在进程中启动爬虫
    crawl_threads = Process(target=main_illness.start_crawl, args=(spider_name ,))
    crawl_threads.start()

    # 启动完线程以后交给工作目录还原
    set_old_path(old_path)

使用进程后,问题解决

三、subprocess.CalledProcessError: Command '['scrapy', 'crawl', 'zhkw', '-o', 'output.json']' returned non-zero exit status 2.

问题描述:

这个问题是在出现问题二之后,我采用的一个解决方法时报的错,使用subprocess子进程启动爬虫,尝试解决ValueError: signal only works in main thread

问题分析:

subprocess来启动scrapy思路是可行的,只不过在这里并没有执行成功,是因为这是在更改工作空间之前,所以会报错。但是使用此方法会有一个缺陷,虽然再子进程中启动了scrapy但是爬虫依然在阻塞,接口就会一直处于阻塞状态,所以建议使用多进程解决。

具体关于阻塞在问题四中会详细介绍

四、接口调用爬虫就会阻塞

问题描述:

由于本项目是由Flask提供接口来启动爬虫,但是爬虫往往都是运行时间很长,接口肯定是不能一直在等待爬虫运行完才结束

解决思路:

我们都知道进程和线程都是异步执行的,最开始我的解决办法就是使用多线程来启动每个爬虫,然后启动线程之后直接返回,爬虫在线程中继续运行。但是后来遇到了问题二,所以就结合问题二使用多进程来启动爬虫。

 

以上就是对Flask结合Scrapy中遇到的问题的解决,大家看了还有不清楚的地方,可以私信或者评论,我都会尽力解答。

另外,由于本人技术有限,此博客有何不对的地方欢迎大家指正,谢谢。

 

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

关于Flask框架中启动Scrapy爬虫框架时的几种问题的解决 的相关文章

  • 如何使用 cython 编译扩展?

    我正在尝试从示例页面编译一个简单的 cython 扩展here http docs cython org src userguide tutorial html在我安装了 Python 2 6 64 位版本的 Windows 7 64 位计
  • 没有任何元数据的 zip 文件

    我想找到一种简单的方法来压缩一堆文件 而无需任何文件元数据 例如时间戳 这zip命令似乎总是保留元数据 我没有找到禁用元数据的方法 我希望解决方案是一个命令或最多一个 python 脚本 谢谢 正如一些帖子已经指出的那样 zip 标头中的大
  • 在 Pandas 中按日期获取有效合约

    我在检测 pandas DataFrame 中的活动合约方面遇到了一些困难 假设每一行都是一个协商 对于每一行 我有两列 initial date 和 end date 我想知道的是按日期划分的活跃合约数量 到目前为止我做了一个非常低效的方
  • 在 Python 中使用 Selenium 处理“接受 Cookie”弹出窗口

    我一直在尝试用硒抓取这个房地产网站的一些信息 但是 当我访问该网站时 我需要接受 cookie 才能继续 这仅在机器人访问网站时发生 而不是在我手动执行时发生 当我尝试通过 xpath 或 id 查找相应的元素时 正如我在手动检查页面时找到
  • 从正在运行的 python 脚本检测优化标志是否为 -O 或 -OO

    有时我想生成一个子进程 其优化标志与启动父进程时使用的优 化标志相同 我可以使用类似的东西 optimize not debug 但这样我就可以匹配两者 O and OO flags 是否有一些 python 内部状态包含该信息 经过一番深
  • 行未从树视图复制

    该行未在树视图中复制 我在按行并复制并粘贴到未粘贴的任何地方后制作了弹出复制 The code popup tk Menu tree opportunity tearoff 0 def row copy item tree opportun
  • python - 是否可以扩展 xml-rpc 可以序列化的事物集?

    我看到几个问题询问如何发送numpy ndarray通过 xml rpc 调用 这不能开箱即用 因为正如 xml rpc 中所述docs https docs python org 2 library xmlrpclib html 有一组固
  • 在python中将文本文件解析为列表

    我对 Python 完全陌生 我正在尝试读取包含单词和数字组合的 txt 文件 我可以很好地读取 txt 文件 但我正在努力将字符串转换为我可以使用的格式 import matplotlib pyplot as plt import num
  • 优化 Keras 以使用所有可用的 CPU 资源

    好吧 我真的不知道我在说什么 所以请耐心听我说 我正在使用 Theano 后端运行 Keras 以在 MNIST 图像上运行基本的神经网络 目前只是一个教程 过去 我一直使用我的旧 HP 笔记本电脑 因为我有 Windows 和 Ubunt
  • “char”/“character”类型的类型提示

    char 或 character 没有内置的原始类型 因此显然必须使用长度为 1 的字符串 但是为了暗示这一点并暗示它应该被视为一个字符 如何通过类型提示来实现这一点 grade chr A 一种方法可能是使用内置的 chr 函数来表示这一
  • 在径向(树)网络x图中查找末端节点(叶节点)

    给定下图 是否有一种方便的方法来仅获取末端节点 我所说的端节点是指那些具有一个连接边的到节点 我认为这些有时被称为叶节点 G nx DiGraph fromnodes 0 1 1 1 1 1 2 3 4 5 5 5 7 8 9 10 ton
  • 具有多个元素的数组的真值是二义性错误吗? Python

    from numpy import from pylab import from math import def TentMap a x if x gt 0 and x lt 0 5 return 2 a x elif x gt 0 5 a
  • 获取列表中倒数第二个元素[重复]

    这个问题在这里已经有答案了 我可以通过以下方式获取列表的倒数第二个元素 gt gt gt lst a b c d e f gt gt gt print lst len lst 2 e 有没有比使用更好的方法print lst len lst
  • 将 Pandas 列中的列表拆分为单独的列

    这是我在 pandas 数据框中的 特征 列 Feature Cricket 82379 Kabaddi 255 Reality 4751 Cricket 15640 Wildlife 730 LiveTV 13 Football 4129
  • Django 在选择列表更改时创建毫无意义的迁移

    我正在尝试使用可调用创建一个带有选择字段的模型 以便 Django 在选择列表更改时不会创建迁移 如中所述this https stackoverflow com questions 31788450 stop django from cr
  • 无法截取宽度为 0 的屏幕截图

    我正在尝试截取 Bootstrap 模态内元素的屏幕截图 经过一番努力 我终于想出了这段代码 driver get https enlinea sunedu gob pe driver find element by xpath div c
  • 查找给定节点的最高权重边

    我在 NetworkX 中有一个有向图 边缘的权重从 0 到 1 表示它们发生的概率 网络连通性非常高 所以我想修剪每个节点的边缘 只保留最高概率的节点 我不确定如何迭代每个节点并仅保留最高权重in edges在图中 有没有一个networ
  • 为什么实现 __iter__ 的对象不被识别为可迭代的?

    假设您使用包装对象 class IterOrNotIter def init self self f open tmp toto txt def getattr self item try return self getattribute
  • 如何在sphinx中启用数学?

    我在用sphinx http sphinx pocoo org index html与pngmath http sphinx pocoo org ext math html module sphinx ext pngmath扩展来记录我的代
  • Django South - 将 null=True 字段转换为 null=False 字段

    我的问题是 转变的最佳做法是什么null True场变成null False使用 Django South 的字段 具体来说 我正在与ForeignKey 你应该先写一个数据迁移 http south aeracode org docs t

随机推荐

  • Keras入门(二)模型的保存、读取及加载

    本文将会介绍如何利用Keras来实现模型的保存 读取以及加载 本文使用的模型为解决IRIS数据集的多分类问题而设计的深度神经网络 DNN 模型 模型的结构示意图如下 具体的模型参数可以参考文章 Keras入门 一 搭建深度神经网络 DNN
  • Mathematica定义函数

    Mathematica定义函数时有点特殊 需在变量后加一个下划线 具体见下面示例 上面示例中定义函数时用的是 其实也可以用 这两个有什么区别呢 具体见下面示例便知 总结 Mathematica定义函数时 变量后面应加一个下划线 然后尽量用
  • DCDC电源负载瞬态响应分析

    DCDC电源负载瞬态响应分析 负载瞬态响应 输出电压过冲现象及其产生原因 如何改善输出电压过冲 负载瞬态响应 当负载电流突然增大或减小时 在us或ns时间内发生较大变化 变化量设置为80 满载输出电流 输出电压的瞬态响应 输出电压过冲现象及
  • springboot处理 json 转换成 实体对象

    可以使用 RequestBody PostMapping add public Result add RequestBody LogisticsDemand demand if demand getRefreshTime null dema
  • Latex-遇到的各种公式和特殊字符

    用的是OverLeaf Sigmoid的写法 begin equation sigma x frac 1 1 e x end equation Softmax的写法 begin equation sigma t i frac e t i s
  • 在Linux(Ubuntu) 中安装mysql服务器并开启远程访问

    在以linux为内核的有centos和ubuntu 推荐大家使用ubuntu 因为使用的人数多 出现了问题方便及时解决问题 一 创建一个云主机 ssh root 39 107 227 105 The authenticity of host
  • 华为OD机试(JAVA)真题II

    华为题库已换 后续会令启专栏更新最新版 介意的勿订阅 介意的勿订阅 介意的勿订阅 华为机试有三道题目 第一道和第二道属于简单或中等题 分值为100分 第三道为中等或困难题 分值为200分 总分为400分 150分钟考试时间 之前通过为150
  • vs2019MSDN(离线帮助文档)的下载与使用

    像这样搬砖的事情最烦了 在这里给大家总结一下步骤 本文参考 https blog csdn net weixin 41234001 article details 103308659 MSDN是vs的一个离线帮助文档 相当于帮助手册 1 检
  • Java中Map.Entry详解

    关于HashMap的详细介绍请参考Java基础 HashMap集合 1 Map Entry简介 Map是java中的接口 Map Entry是Map的一个内部接口 Map提供了一些常用方法 如keySet entrySet 等方法 keyS
  • React16.3新的生命周期详解

    一 React v16 0前的生命周期 1 1 第一个是组件初始化 initialization 阶段 也就是以下代码中类的构造方法 constructor Test类继承了react Component这个基类 也就继承这个react的基
  • skipped by case

    void func void int x switch x case 0 int i 1 error skipped by case 1 int j 1 ok initialized in e
  • 【转载】 C#中使用Count方法获取List集合中符合条件的个数

    很多时候操作List集合的过程中 我们需要根据特定的查询条件 获取List集合中有多少个实体对象符合查询条件 例如一批产品的对象List集合 如果这批产品的不合格数量大于10则重点备注 在C 中可以自己写for循环语句来逐条判断条件来实现
  • buuctf web [极客大挑战 2019]LoveSQL

    又是这样的界面 这糟糕的熟悉感 依旧使用上题套路 用户名 admin or 1 1 密码 1 有一串很像flag的字符 但是很可惜 这不是flag 看了一眼源代码 没有可以跳转的页面 要换个思路了 重新查看题目 发现输入的东西在check
  • Error message & blank display while ZH-cn locale in ai2

    需要修改源码2个文件 1 appinventor sources appinventor appengine war login jsp
  • Allegro修改原点位置

    1 打开Setup菜单栏的Change Drawing Origin命令 在PCB设计界面中 鼠标单击要设置原点的位置即可 2
  • c++基本使用--名字遮蔽与类作用域/继承的特殊关系

    名字遮蔽与类作用域 继承的特殊关系 名字遮蔽 基类的成员函数和派生类的成员函数不会构成重载 如果派生类有同名函数 那么就会遮蔽基类中的所有同名函数 类作用域 继承的特殊关系 名字遮蔽 基类的成员函数和派生类的成员函数不会构成重载 如果派生类
  • 【Leetcode刷题笔记之链表篇】142. 环形链表 II

    博客主页 大家好我叫张同学 欢迎点赞 收藏 留言 欢迎讨论 本文由 大家好我叫张同学 原创 首发于 CSDN 精品专栏 不定时更新 数据结构 算法 做题笔记 C语言编程学习 精品文章推荐 C语言进阶学习笔记 三 字符串函数详解 1 爆肝吐血
  • 如何在window快速安装Linux系统(虚拟机)

    软件名称 VMware17 0 0 安装环境 Win 11 虚拟机是指通过软件模拟的具有完整硬件系统功能的 运行在一个完全隔离环境中的完整计算机系统 虚拟机允许用户在当前操作系统中运行其他操作系统 虚拟操作系统会像电脑上的另一个程序一样运行
  • 算法导论 第六章 堆排序 习题6.5-8 k路合并排序

    请给出一个时间为O nlgk 用来将k个已排序链表合并为一个排序链表的算法 此处n为所有输入链表中元素的总数 提示 用一个最小堆来做k路合并 思路 利用有k个元素的最小堆有lgk的复杂度 所以堆的元素组成要每个链表的一个元素组成 具体步骤
  • 关于Flask框架中启动Scrapy爬虫框架时的几种问题的解决

    最近开发的爬虫调度系统是由Flask框架提供接口 在Flask中启动Scrapy项目 开发期间遇到了几个问题 网上找找 自己也琢磨了好久 终于顺利解决 问题如下 一 Scrapy crawl指令找不到 问题描述 先看一下我的项目结构 如下