You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何修复Scrapy的Unsupported URL scheme错误?

解决Scrapy + Flask 集成中的URL Scheme错误及其他问题

你遇到的核心错误是URL缺少HTTP/HTTPS协议头,但代码里还有几个其他需要修正的问题,我来一步步帮你解决:

1. 直接触发错误的根源:URL Scheme缺失

Scrapy必须依赖明确的http://或https://协议头才能识别并处理请求,你传入的www.google.com没有协议前缀,Scrapy会判定它的URL Scheme为空,从而抛出Unsupported URL scheme ''错误。

修复方式:

在接收请求或初始化爬虫时,自动为URL补充协议头:

# 在Flask路由中处理URL
url = request.json['url']
if not url.startswith(('http://', 'https://')):
    url = f'https://{url}'

也可以在爬虫的__init__方法中做相同检查,确保start_urls里的URL均带有合法协议。

2. 代码中的语法错误

你写的self.start_urlsappend(url)存在语法问题,正确写法是:

self.start_urls.append(url)

更简洁的方式是直接初始化列表:

self.start_urls = [url]

3. 爬虫运行逻辑的致命问题

你当前用subprocess调用Scrapy的方式有两个关键缺陷:

  • 你传递了self.start_urls(一个列表)给-a url=参数,这会让Scrapy收到类似['www.google.com']的字符串,显然不是合法URL。
  • 更重要的是:subprocess启动的Scrapy进程与Flask进程完全独立,内存不共享,因此self.news不会被Scrapy进程填充,最终返回的是空列表。

推荐修复方案:用Scrapy的CrawlerProcess直接在Flask进程内运行爬虫

这种方式可以直接获取爬虫结果,无需依赖外部文件或进程间通信,更符合Python应用的集成逻辑。

修改后的完整代码示例:

from flask import Flask, jsonify, request
import scrapy
from scrapy.crawler import CrawlerProcess
from scrapy.utils.project import get_project_settings
from scrapy import signals
from scrapy.signalmanager import dispatcher

app = Flask(__name__)

class ClassSpider(scrapy.Spider):
    name = 'mySpider'

    def __init__(self, url, nbrPage):
        self.pages = nbrPage
        # 确保URL带合法协议头
        if not url.startswith(('http://', 'https://')):
            url = f'https://{url}'
        self.start_urls = [url]

    def parse(self, response):
        # 替换为你的实际解析逻辑,示例提取页面标题
        title = response.css('h1::text').get()
        if title:
            # 使用yield返回item,这是Scrapy的标准做法
            yield {'title': title.strip()}
        
        # 分页逻辑示例(根据你的需求调整)
        if self.pages > 1:
            next_page = response.css('a.next-page::attr(href)').get()
            if next_page:
                self.pages -= 1
                yield response.follow(next_page, self.parse)

def run_spider(url, nbrPage):
    """辅助函数:运行爬虫并收集结果"""
    results = []
    
    def collect_item(item, response, spider):
        results.append(item)
    
    # 连接Scrapy信号,实时收集爬取到的item
    dispatcher.connect(collect_item, signal=signals.item_scraped)
    
    # 初始化爬虫进程
    process = CrawlerProcess(get_project_settings())
    process.crawl(ClassSpider, url=url, nbrPage=nbrPage)
    process.start()  # 阻塞直到爬虫运行完成
    
    return results

@app.route('/', methods=['POST'])
def getNews():
    try:
        url = request.json['url']
        news_data = run_spider(url, 2)
        return jsonify({'data': news_data})
    except Exception as e:
        return jsonify({'error': str(e)}), 400

if __name__ == "__main__":
    app.run(debug=True)

额外注意事项

  • 确保你的Scrapy项目存在settings.py文件(可通过scrapy startproject生成项目框架,再将爬虫放入对应目录),或手动配置CrawlerProcess的运行参数。
  • Flask默认是多线程模式,使用信号收集结果是线程安全的,比用类属性存储结果更可靠。
  • 如果你的爬虫需要处理大量请求,建议引入异步任务队列(如Celery)来运行爬虫,避免阻塞Flask主线程影响服务响应。

内容的提问来源于stack exchange,提问作者Med ADDOU

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.07 21:43:00