从 Flask 运行 Scrapy

2024-01-05

我有这个文件夹结构:

app.py # flask app
app/
   datafoo/
          scrapy.cfg
          crawler.py
          blogs/
                pipelines.py 
                settings.py
                middlewares.py
                items.py
                spiders/                    
                        allmusic_feed.py
                        allmusic_data/
                                      delicate_tracks.jl
                                     
                                     
                      

                
          

scrapy.cfg:

[settings]
default = blogs.settings

allmusic_feed.py:

   class AllMusicDelicateTracks(scrapy.Spider): # one amongst many spiders
        name = "allmusic_delicate_tracks"
        allowed_domains = ["allmusic.com"]
        start_urls = ["http://web.archive.org/web/20160813101056/http://www.allmusic.com/mood/delicate-xa0000000972/songs",             
        ]
        def parse(self, response):
    
            for sel in response.xpath('//tr'):
                item = AllMusicItem()
                item['artist'] = sel.xpath('.//td[@class="performer"]/a/text()').extract_first() 
                item['track'] = sel.xpath('.//td[@class="title"]/a/text()').extract_first()
                yield item

爬虫.py:

from twisted.internet import reactor
from scrapy.crawler import CrawlerProcess
from scrapy.utils.project import get_project_settings 


def blog_crawler(self, mood):

        item, jl = mood  # ITEM = SPIDER
        process = CrawlerProcess(get_project_settings())
        process.crawl(item, domain='allmusic.com')
        process.start() 
        allmusic = []
        allmusic_tracks = []
        allmusic_artists = []
        try:
            # jl is file where crawled data is stored
            with open(jl, 'r+') as t:
                for line in t:
                    allmusic.append(json.loads(line))
        except Exception as e:
            print (e, 'try another mood')

        for item in allmusic:
            allmusic_artists.append(item['artist'])
            allmusic_tracks.append(item['track'])
        return zip(allmusic_tracks, allmusic_artists)

app.py :

@app.route('/tracks', methods=['GET','POST'])
def tracks(name):
    from app.datafoo import crawler

    c = crawler()
    mood = ['allmusic_delicate_tracks', 'blogs/spiders/allmusic_data/delicate_tracks.jl']
    results = c.blog_crawler(mood)
    return results

如果只是运行应用程序python app.py,我收到以下错误:

ValueError: signal only works in main thread

当我运行应用程序时gunicorn -c gconfig.py app:app --log-level=debug --threads 2 ,它就挂在那里:

127.0.0.1 - - [29/Jan/2018:03:40:36 -0200] "GET /tracks HTTP/1.1" 500 291 "http://127.0.0.1:8080/menu" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36"

最后,运行gunicorn -c gconfig.py app:app --log-level=debug --threads 2 --error-logfile server.log, I get:

服务器日志

[2018-01-30 13:41:39 -0200] [4580] [DEBUG] Current configuration:
  proxy_protocol: False
  worker_connections: 1000
  statsd_host: None
  max_requests_jitter: 0
  post_fork: <function post_fork at 0x1027da848>
  errorlog: server.log
  enable_stdio_inheritance: False
  worker_class: sync
  ssl_version: 2
  suppress_ragged_eofs: True
  syslog: False
  syslog_facility: user
  when_ready: <function when_ready at 0x1027da9b0>
  pre_fork: <function pre_fork at 0x1027da938>
  cert_reqs: 0
  preload_app: False
  keepalive: 5
  accesslog: -
  group: 20
  graceful_timeout: 30
  do_handshake_on_connect: False
  spew: False
  workers: 16
  proc_name: None
  sendfile: None
  pidfile: None
  umask: 0
  on_reload: <function on_reload at 0x10285c2a8>
  pre_exec: <function pre_exec at 0x1027da8c0>
  worker_tmp_dir: None
  limit_request_fields: 100
  pythonpath: None
  on_exit: <function on_exit at 0x102861500>
  config: gconfig.py
  logconfig: None
  check_config: False
  statsd_prefix: 
  secure_scheme_headers: {'X-FORWARDED-PROTOCOL': 'ssl', 'X-FORWARDED-PROTO': 'https', 'X-FORWARDED-SSL': 'on'}
  reload_engine: auto
  proxy_allow_ips: ['127.0.0.1']
  pre_request: <function pre_request at 0x10285cde8>
  post_request: <function post_request at 0x10285ced8>
  forwarded_allow_ips: ['127.0.0.1']
  worker_int: <function worker_int at 0x1027daa28>
  raw_paste_global_conf: []
  threads: 2
  max_requests: 0
  chdir: /Users/me/Documents/Code/Apps/app
  daemon: False
  user: 501
  limit_request_line: 4094
  access_log_format: %(h)s %(l)s %(u)s %(t)s "%(r)s" %(s)s %(b)s "%(f)s" "%(a)s"
  certfile: None
  on_starting: <function on_starting at 0x10285c140>
  post_worker_init: <function post_worker_init at 0x10285c848>
  child_exit: <function child_exit at 0x1028610c8>
  worker_exit: <function worker_exit at 0x102861230>
  paste: None
  default_proc_name: app:app
  syslog_addr: unix:///var/run/syslog
  syslog_prefix: None
  ciphers: TLSv1
  worker_abort: <function worker_abort at 0x1027daaa0>
  loglevel: debug
  bind: ['127.0.0.1:8080']
  raw_env: []
  initgroups: False
  capture_output: False
  reload: False
  limit_request_field_size: 8190
  nworkers_changed: <function nworkers_changed at 0x102861398>
  timeout: 120
  keyfile: None
  ca_certs: None
  tmp_upload_dir: None
  backlog: 2048
  logger_class: gunicorn.glogging.Logger
[2018-01-30 13:41:39 -0200] [4580] [INFO] Starting gunicorn 19.7.1
[2018-01-30 13:41:39 -0200] [4580] [DEBUG] Arbiter booted
[2018-01-30 13:41:39 -0200] [4580] [INFO] Listening at: http://127.0.0.1:8080 (4580)
[2018-01-30 13:41:39 -0200] [4580] [INFO] Using worker: threads
[2018-01-30 13:41:39 -0200] [4580] [INFO] Server is ready. Spawning workers
[2018-01-30 13:41:39 -0200] [4583] [INFO] Booting worker with pid: 4583
[2018-01-30 13:41:39 -0200] [4583] [INFO] Worker spawned (pid: 4583)
[2018-01-30 13:41:39 -0200] [4584] [INFO] Booting worker with pid: 4584
[2018-01-30 13:41:39 -0200] [4584] [INFO] Worker spawned (pid: 4584)
[2018-01-30 13:41:39 -0200] [4585] [INFO] Booting worker with pid: 4585
[2018-01-30 13:41:39 -0200] [4585] [INFO] Worker spawned (pid: 4585)
[2018-01-30 13:41:40 -0200] [4586] [INFO] Booting worker with pid: 4586
[2018-01-30 13:41:40 -0200] [4586] [INFO] Worker spawned (pid: 4586)
[2018-01-30 13:41:40 -0200] [4587] [INFO] Booting worker with pid: 4587
[2018-01-30 13:41:40 -0200] [4587] [INFO] Worker spawned (pid: 4587)
[2018-01-30 13:41:40 -0200] [4588] [INFO] Booting worker with pid: 4588
[2018-01-30 13:41:40 -0200] [4588] [INFO] Worker spawned (pid: 4588)
[2018-01-30 13:41:40 -0200] [4589] [INFO] Booting worker with pid: 4589
[2018-01-30 13:41:40 -0200] [4589] [INFO] Worker spawned (pid: 4589)
[2018-01-30 13:41:40 -0200] [4590] [INFO] Booting worker with pid: 4590
[2018-01-30 13:41:40 -0200] [4590] [INFO] Worker spawned (pid: 4590)
[2018-01-30 13:41:40 -0200] [4591] [INFO] Booting worker with pid: 4591
[2018-01-30 13:41:40 -0200] [4591] [INFO] Worker spawned (pid: 4591)
[2018-01-30 13:41:40 -0200] [4592] [INFO] Booting worker with pid: 4592
[2018-01-30 13:41:40 -0200] [4592] [INFO] Worker spawned (pid: 4592)
[2018-01-30 13:41:40 -0200] [4595] [INFO] Booting worker with pid: 4595
[2018-01-30 13:41:40 -0200] [4595] [INFO] Worker spawned (pid: 4595)
[2018-01-30 13:41:40 -0200] [4596] [INFO] Booting worker with pid: 4596
[2018-01-30 13:41:40 -0200] [4596] [INFO] Worker spawned (pid: 4596)
[2018-01-30 13:41:40 -0200] [4597] [INFO] Booting worker with pid: 4597
[2018-01-30 13:41:40 -0200] [4597] [INFO] Worker spawned (pid: 4597)
[2018-01-30 13:41:40 -0200] [4598] [INFO] Booting worker with pid: 4598
[2018-01-30 13:41:40 -0200] [4598] [INFO] Worker spawned (pid: 4598)
[2018-01-30 13:41:40 -0200] [4599] [INFO] Booting worker with pid: 4599
[2018-01-30 13:41:40 -0200] [4599] [INFO] Worker spawned (pid: 4599)
[2018-01-30 13:41:40 -0200] [4600] [INFO] Booting worker with pid: 4600
[2018-01-30 13:41:40 -0200] [4600] [INFO] Worker spawned (pid: 4600)
[2018-01-30 13:41:40 -0200] [4580] [DEBUG] 16 workers
[2018-01-30 13:41:47 -0200] [4583] [DEBUG] GET /menu
[2018-01-30 13:41:54 -0200] [4584] [DEBUG] GET /tracks

NOTE:

in this 所以答案 https://stackoverflow.com/questions/36384286/how-to-integrate-flask-scrapy我了解到,为了集成 Flask 和 Scrapy,你可以使用:

1.Python子进程

2. Twisted-Klein + Scrapy

3.ScrapyRT

但我没有运气将我的特定代码适应这些解决方案。

我认为子流程会更简单且足够,因为用户体验很少需要抓取线程,但我不确定。

谁能在这里指出正确的方向吗?


这是一个如何使用 ScrapyRT 完成此操作的最小示例。

这是项目结构:

project/
├── scraping
│   ├── example
│   │   ├── __init__.py
│   │   ├── items.py
│   │   ├── middlewares.py
│   │   ├── pipelines.py
│   │   ├── settings.py
│   │   └── spiders
│   │       ├── __init__.py
│   │       └── quotes.py
│   └── scrapy.cfg
└── webapp
    └── example.py

scraping目录包含 Scrapy 项目。该项目包含一只蜘蛛quotes.py从中抓取一些引用报价.toscrape.com http://quotes.toscrape.com/:

# -*- coding: utf-8 -*-
from __future__ import unicode_literals

import scrapy


class QuotesSpider(scrapy.Spider):
    name = 'quotes'
    start_urls = ['http://quotes.toscrape.com/']

    def parse(self, response):
        for quote in response.xpath('//div[@class="quote"]'):
            yield {
                'author': quote.xpath('.//small[@class="author"]/text()').extract_first(),
                'text': quote.xpath('normalize-space(./span[@class="text"])').extract_first()
            }

为了启动 ScrapyRT 并监听抓取请求,请转到 Scrapy 项目的目录scraping并发出scrapyrt命令:

$ cd ./project/scraping
$ scrapyrt

ScrapyRT 现在将监听本地主机:9080 http://localhost:9080.

webapp目录包含简单的 Flask 应用程序,可以按需抓取报价(使用上面的蜘蛛)并简单地将它们显示给用户:

from __future__ import unicode_literals

import json
import requests

from flask import Flask

app = Flask(__name__)

@app.route('/')
def show_quotes():
    params = {
        'spider_name': 'quotes',
        'start_requests': True
    }
    response = requests.get('http://localhost:9080/crawl.json', params)
    data = json.loads(response.text)
    result = '\n'.join('<p><b>{}</b> - {}</p>'.format(item['author'], item['text'])
                       for item in data['items'])
    return result

启动应用程序:

$ cd ./project/webapp
$ FLASK_APP=example.py flask run

现在,当您将浏览器指向本地主机:5000 http://localhost:5000/,您将看到刚从其中抓取的报价列表报价.toscrape.com http://quotes.toscrape.com/.

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

从 Flask 运行 Scrapy 的相关文章

  • 用 Python 编写一个无操作或虚拟类

    假设我有这样的代码 foo fooFactory create 由于种种原因 fooFactory create 可能无法创建实例Foo 如果可以的话我想要fooFactory create 返回一个虚拟 无操作对象 这个对象应该是完全惰性
  • 类属性在功能上依赖于其他类属性

    我正在尝试使用静态类属性来定义另一个静态类属性 我认为可以通过以下代码来实现 f lambda s s 1 class A foo foo bar f A foo 然而 这导致NameError name A is not defined
  • 如何自动替换多个文件的文本内容中的字符?

    我有一个文件夹 myfolder包含许多乳胶表 我需要替换其中每个字符 即替换任何minus sign by an en dash 只是为了确定 我们正在替换连字符INSIDE该文件夹中的所有 tex 文件 我不关心 tex 文件名 手动执
  • 如何将条目中的部分文本加粗并更改其背景颜色?

    我正在创建一个基于 Tkinter 的 GUI 它有一个 Entry 小部件 我想将其文本的一部分加粗并更改其背景颜色 但我不知道我该怎么做 如果我使用文本小部件 我可以只使用标签 但看起来它们不能与条目小部件一起使用 此代码使用文本小部件
  • 使用正则表达式解析 Snort 警报文件

    我正在尝试使用 Python 中的正则表达式从 snort 警报文件中解析出源 目标 IP 和端口 和时间戳 示例如下 03 09 14 10 43 323717 1 2008015 9 ET MALWARE User Agent Win9
  • 将一个时间序列插入到 pandas 中的另一个时间序列中

    我有一组定期测量的值 说 import pandas as pd import numpy as np rng pd date range 2013 01 01 periods 12 freq H data pd Series np ran
  • 将 subprocess.Popen 的输出通过管道传输到文件

    我需要启动一些长时间运行的进程subprocess Popen 并希望拥有stdout and stderr从每个自动管道到单独的日志文件 每个进程将同时运行几分钟 我想要两个日志文件 stdout and stderr 每个进程当进程运行
  • 反加入熊猫

    我有两个表 我想附加它们 以便仅保留表 A 中的所有数据 并且仅在其键唯一时添加表 B 中的数据 键值在表 A 和 B 中是唯一的 但在某些情况下键将出现在表 A 和 B 中 我认为执行此操作的方法将涉及某种过滤联接 反联接 以获取表 B
  • Python While 循环,and (&) 运算符不起作用

    我正在努力寻找最大公因数 我写了一个糟糕的 运算密集型 算法 它将较低的值减一 使用 检查它是否均匀地划分了分子和分母 如果是 则退出程序 但是 我的 while 循环没有使用 and 运算符 因此一旦分子可整除 它就会停止 即使它不是正确
  • 在 Windows 上使用 IPython 笔记本时出现 500 服务器错误

    我刚刚在 Windows 7 Professional 64 位上全新安装了 IPython 笔记本 我采取的步骤是 从以下位置安装 Python 3 4 1http python org http python org gt pip in
  • Python int 太大,无法放入 SQLite

    我收到错误 OverflowError Python int 太大 无法转换为 SQLite INTEGER 来自以下代码块 该文件约25GB 因此必须分部分读取 length 6128765 Works on partitions of
  • 负整数的Python表示

    gt gt gt x 4 gt gt gt print b format x x 4 100 gt gt gt mask 0xFFFFFFFF gt gt gt print b format x mask x mask 4294967292
  • 在 pip.conf 中指定多个可信主机

    这是我尝试在我的中设置的 etc pip conf global trusted host pypi org files pythonhosted org 但是 它无法正常工作 参考 https pip pypa io en stable
  • WindowsError:[错误 5] 访问被拒绝

    我一直在尝试终止一个进程 但我的所有选项都给出了 Windows 访问被拒绝错误 我通过以下方式打开进程 一个python脚本 test subprocess Popen sys executable testsc py 我想杀死那个进程
  • 使用 lambda 函数更改属性值

    我可以使用 lambda 函数循环遍历类对象列表并更改属性值 对于所有对象或满足特定条件的对象 吗 class Student object def init self name age self name name self age ag
  • Python模块单元测试的最佳文件结构组织?

    遗憾的是 我发现有太多方法可以在 Python 中保存单元测试 而且它们通常没有很好的文档记录 我正在寻找一种 终极 结构 它可以满足以下大部分要求 be discoverable by test frameworks including
  • CSV 在列中查找最大值并附加新数据

    大约两个小时前 我问了一个关于从网站读取和写入数据的问题 从那时起 我花了最后两个小时试图找到一种方法来从输出的 A 列读取最大日期值 将该值与刷新的网站数据进行比较 并将任何新数据附加到 csv 文件而不覆盖旧的或创建重复项 目前 100
  • Google App Engine 中的自定义身份验证

    有谁知道或知道我可以在哪里学习如何使用 Python 和 Google App Engine 创建自定义身份验证流程 我不想使用 Google 帐户进行身份验证 并且希望能够创建自己的用户 如果不是专门针对 Google App Engin
  • PyQt 中的线程和信号问题

    我在 PyQt 中的线程之间进行通信时遇到一些问题 我使用信号在两个线程 发送者和监听者 之间进行通信 发送者发送消息 期望被监听者接收 但是 没有收到任何消息 谁能建议可能出了什么问题 我确信这一定很简单 但我已经环顾了几个小时但没有发现
  • 使用 Keras 和 fit_generator 绘制 TensorBoard 分布和直方图

    我正在使用 Keras 使用 fit generator 函数训练 CNN 这似乎是一个已知问题 https github com fchollet keras issues 3358TensorBoard 在此设置中不显示直方图和分布 有

随机推荐

  • r Markdown 的 Yaml 标头中的单引号和双引号有什么区别?

    我在 RStudio 中使用 knit 编译的 r Markdown 文件中遇到错误 我不太确定这个 错误 应该指向哪里 这似乎并不是一个 R 错误 如果我使用以下 YAML 标头内容创建 R markdown 文档 我可以很好地编织该文件
  • winsock中的异步地址解析?

    查看winsock中的异步地址解析 似乎唯一的两个选择是使用阻塞gethostbyname在单独的线程上 或使用WSAAsyncGetHostByName 出于某种原因 后者被设计为处理窗口消息 而不是重叠操作和完成端口 例程 有没有什么版
  • Python Mechanize 选择表单 FormNotFoundError

    我想选择带有机械化的形式 这是我的代码 br mechanize Browser self br open url br select form name login form 表格的代码
  • 在 C++ 中不打开文件检查文件大小?

    我正在尝试获取大文件 12gb 的文件大小 但我不想打开该文件来执行此操作 因为我认为这会消耗大量资源 有没有什么好的API可以做到这一点 我是在Windows环境下 你应该打电话GetFileSizeEx http msdn micros
  • 如何使用numpy生成分段间隔上的随机数

    我正在 python 中使用 numpy 模块来生成随机数 当我需要生成连续区间的随机数如 a b 时 我会使用 b a np random rand 1 a 但现在我需要生成区间 a b 和 c d 内的均匀随机数 我该怎么办 我想生成一
  • ConnectNamedPipe 和 asio 重叠的 ptr

    我将管道服务器命名为使用 boost asio 编写的 服务器创建命名管道并调用 ConnectNamedPipe 将 asio 重叠 ptr 传递给它 问题是传递给 asiooverlaped 的完成处理程序永远不会被调用 即在客户端调用
  • 如何在android studio中启用版本控制窗口

    对于我的某些分支 我无法获得版本控制窗口 例如 如果我进入分支develop 然后窗口显示 如果我进入master它已经消失了 我无能为力把它找回来 我试图通过从开发到掌握来欺骗它 但一旦我掌握了 它又消失了 该问题相对较新 7 天 过去不
  • 为什么 Scala 案例类字段不反映为公共字段?

    我一直将案例类的构造函数参数理解为定义公共值 但是 当我反映这些字段时 isPublic 方法出现错误 有什么想法吗 scala gt class Test val name String val num Int defined class
  • 自定义 Ansible 回调未接收 group_vars/host_vars

    我正在编写一个自定义的 ansible 回调 class CallbackModule CallbackBase CALLBACK VERSION 2 0 CALLBACK TYPE aggregate CALLBACK NAME my c
  • 如何在mayavi(imshow)中绘制彩色图像

    是否可以使用mayavi绘制具有3个颜色通道的图像 根据 mayavi 的文档 mayavi mlab imshow只能处理形状为 n x m 的图像 Method 我必须使用 Mayavi 的自定义色彩图 请参阅http docs ent
  • 用于网站和 Api 的 Ninject - 序列不包含元素

    我有一个带有 Web Api 项目和 MVC 3 项目的 VS2010 解决方案 Web APi 和 MVC 项目都有自己的 App Start 和 NinjectWebCommon 并在其中声明了自己的绑定 当尝试使用 Api 时 我总是
  • PHP 中的 OOP:来自变量的类函数?

    是否可以像这样从类中调用函数 class new class function name do the thing req class gt function name 类似的解决方案 这似乎不起作用 是的 这是可能的 这就是众所周知的变量
  • 在单个 ASP.NET Core WebAPI 服务中托管多个产品 API

    我正在设计一个基于 ASP NET Core 的 Web API 它需要支持我的产品的多个变体 比方说基于许可证或安装的品种 我没有为每种类型的产品提供多种服务 而是考虑使用一个服务来容纳 托管多个端点或 URL 我将在安装时在 appse
  • 如何在c中读取图像的像素?

    假设我们的位图图像具有高度 M 和宽度 N 我们总是假设 在本实验中 宽度 N 是 4 的倍数 这简化了 文件中的字节布局 对于该图像 像素数组存储 正好 3 x N x M 字节 如下所示 每组 3 个字节代表一个像素 其中字节存储 按顺
  • 如何在 main 中设置 Nimbus 外观

    我刚刚学习Java 仍然无法解决我遇到的这个小问题 我的弹出日历使用 Nimbus 外观和感觉 但我有使用 Java 外观和感觉的面板和容器 Jtable 我试图使每个 GUI 屏幕 窗口都使用 Nimbus 外观和感觉 Merky 建议将
  • 从 numpy 数组到 DICOM

    我的代码读取 DICOM 文件 将像素信息放入 numpy 数组 然后修改 numpy 数组 它使用列表是因为我试图同时操作多个 DICOM 文件 我还没有找到任何关于如何获取修改后的 numpy 数组并再次使其成为 DICOM 文件的信息
  • 通过 Windows API 检索 PCI 坐标(用户模式)

    有没有办法使用 Windows c c API 例如 PnP Configuration Manager API 获取设备的 PCI 坐标 总线 插槽 功能号 我已经知道如何在内核模式下执行此操作 我需要一个用户模式解决方案 我的目标系统是
  • 在“for”循环中递增 1 时格式化背后的技术原因?

    整个网络上都有代码示例for循环看起来像这样 for int i 0 i lt 5 i 当我使用以下格式时 for int i 0 i 5 i 我这样做是因为我相信这样会更有效率 但是在大多数情况下这真的很重要吗 每个人都喜欢他们的微观优化
  • 使用来自 json 文件的字符串将字符串数组传递给 React 组件,并允许内联 span 标签

    我正在尝试获取一个字符串数组来显示为段落 并允许在这些字符串内使用内联跨度标签 我的问题是 当在段落内添加值时 会将 标记的开头和结尾解码为其解码值 有没有一种简单的方法可以使其工作而无需为此情况制作特定组件 我的React组件如下 con
  • 从 Flask 运行 Scrapy

    我有这个文件夹结构 app py flask app app datafoo scrapy cfg crawler py blogs pipelines py settings py middlewares py items py spid