【问题标题】:Scrapy Value Error f'Missing scheme in requestScrapy Value Error f'Missing scheme in request
【发布时间】:2022-01-16 21:17:06
【问题描述】:

我是scrapy的新手,我正在尝试废弃https:opensports。我需要来自所有产品的一些数据,所以我的想法是获得所有品牌(如果我获得所有品牌,我将获得所有产品)。每个 url 的品牌,有很多页(每页 24 篇文章),所以我需要定义每个品牌的总页数,然后获取从 1 到总页数的链接。 我正面临一个(或更多!)hrefs 问题...这是脚本:

 import scrapy
 from scrapy import Request
 from scrapy.crawler import CrawlerProcess
 from datetime import datetime
 import datetime

 #start_url: https://www.opensports.com.ar/marcas.html
 class SolodeportesSpider(scrapy.Spider):
     name = 'solodeportes'
     start_urls = ['https://www.opensports.com.ar/marcas.html']
     custom_settings = {'FEED_URI':'opensports_' + f'{datetime.datetime.today().strftime("%d-%m-%Y-%H%M%S")}.csv', 'FEED_FORMAT': 'csv', }

     #get links of dif. brands 
     def parse(self, response):
         marcas= response.css('#maincontent > div.category-view > div > div.brands-page > table > tbody  td a::attr(href)').getall()
         for marca in marcas:
             yield Request(marca, self.parse_paginator)

     #get total number of pages of the brand And request all pages from 1 to  total number of products
     def parse_paginator(self,response):
         total_products = int(int(response.css('#toolbar-amount > span:nth-child(3)::text').get() / 24) + 1)
         for count in range(1, total_products):
             yield Request(url=f'https://www.opensports.com.ar/{response.url}?p={count}',
                      callback=self.parse_listings)



     #Links list to click to get the articles detail
     def parse_listings(self, response):
         all_listings = response.css('a.product-item-link::attr(class)').getall()
         for url in all_listings:
             yield Request(url, self.detail_page)

     #url--Article-- Needed data
     def detail_page(self, response):
        yield {
        'Nombre_Articulo' :response.css('h1.page-title span::text').get(),
        'Precio_Articulo' : response.css('span.price::text').get(),
        'Sku_Articulo' : response.css('td[data-th="SKU"]::text').get() ,
        'Tipo_Producto': response.css('td[data-th="Disciplina"]::text').get() ,
        'Item_url': response.url
    }


 process = CrawlerProcess()
 process.crawl(SolodeportesSpider)
 process.start()

我收到此错误消息:

c:/Users/User/Desktop/Personal/DABRA/Scraper_opensports/opensports/opens_sp_copia_solod.py 2022-01-16 03:45:05 [scrapy.utils.log] 信息:Scrapy 2.5.1 开始 (机器人:scrapybot)2022-01-16 03:45:05 [scrapy.utils.log] 信息: 版本:lxml 4.7.1.0、libxml2 2.9.12、cssselect 1.1.0、parsel 1.6.0、w3lib 1.22.0、Twisted 21.7.0、Python 3.10.1(tags/v3.10.1:2cd268a,2021 年 12 月 6 日,19:10:37)[MSC v.1929 64 位
(AMD64)],pyOpenSSL 21.0.0(OpenSSL 1.1.1m 2021 年 12 月 14 日),密码学 36.0.1,平台 Windows-10-10.0.19042-SP0 2022-01-16 03:45:05 [scrapy.utils.log] 调试:使用反应器:
twisted.internet.selectreactor.SelectReactor 2022-01-16 03:45:05 [scrapy.crawler] 信息:覆盖设置:{} 2022-01-16 03:45:05 [scrapy.extensions.telnet] 信息:Telnet 密码:b362a63ff2281937
2022-01-16 03:45:05 [py.warnings] 警告:
C:\Users\User\Desktop\Personal\DABRA\Scraper_opensports\venv\lib\site- 包\scrapy\extensions\feedexport.py:247: ScrapyDeprecationWarning:FEED_URIFEED_FORMAT 设置 已弃用,取而代之的是 FEEDS 设置。请看
FEEDS 设置文档了解更多详情 exporter = cls(crawler)

2022-01-16 03:45:05 [scrapy.middleware] 信息:启用的扩展: ['scrapy.extensions.corestats.CoreStats', 'scrapy.extensions.telnet.TelnetConsole', 'scrapy.extensions.feedexport.FeedExporter', 'scrapy.extensions.logstats.LogStats'] 2022-01-16 03:45:05 [scrapy.middleware] 信息:已启用下载器中间件: ['scrapy.downloadermiddlewares.httpauth.HttpAuthMiddleware', 'scrapy.downloadermiddlewares.downloadtimeout.DownloadTimeoutMiddleware', 'scrapy.downloadermiddlewares.defaultheaders.DefaultHeadersMiddleware', 'scrapy.downloadermiddlewares.useragent.UserAgentMiddleware', 'scrapy.downloadermiddlewares.retry.RetryMiddleware', 'scrapy.downloadermiddlewares.redirect.MetaRefreshMiddleware', 'scrapy.downloadermiddlewares.httpcompression.HttpCompressionMiddleware', 'scrapy.downloadermiddlewares.redirect.RedirectMiddleware', 'scrapy.downloadermiddlewares.cookies.CookiesMiddleware', 'scrapy.downloadermiddlewares.httpproxy.HttpProxyMiddleware', 'scrapy.downloadermiddlewares.stats.DownloaderStats'] 2022-01-16 03:45:05 [scrapy.middleware] 信息:启用蜘蛛中间件: ['scrapy.spidermiddlewares.httperror.HttpErrorMiddleware', 'scrapy.spidermiddlewares.offsite.OffsiteMiddleware', 'scrapy.spidermiddlewares.referer.RefererMiddleware', 'scrapy.spidermiddlewares.urllength.UrlLengthMiddleware', 'scrapy.spidermiddlewares.depth.DepthMiddleware'] 2022-01-16 03:45:05 [scrapy.middleware] INFO:启用项目管道:[] 2022-01-16 03:45:05 [scrapy.core.engine] 信息:Spider 打开 2022-01-16 03:45:05 [scrapy.extensions.logstats] 信息:抓取 0 页(以 0 页/分钟), 刮掉 0 件(以 0 件/分钟计算) 2022-01-16 03:45:05 [scrapy.extensions.telnet] 信息:Telnet 控制台正在监听 127.0.0.1:6023 2022-01-16 03:45:07 [scrapy.core.engine] 调试:已爬网(200)https://www.opensports.com.ar/marcas.html>(引用:无) 2022-01-16 03:45:07 [scrapy.core.scraper] 错误:蜘蛛错误 处理https://www.opensports.com.ar/marcas.html>(参考: 无)回溯(最近一次通话最后一次):文件 "C:\Users\User\Desktop\Personal\DABRA\Scraper_opensports\venv\lib\site-packages\scrapy\utils\defer.py", 第 120 行,在 iter_errback 中 产生下一个(它)文件“C:\用户\用户\桌面\个人\DABRA\Scraper_opensports\venv\lib\site-packages\scrapy\utils\python.py”, 第 353 行,在 下一个 返回下一个(self.data)文件“C:\Users\User\Desktop\Personal\DABRA\Scraper_opensports\venv\lib\site-packages\scrapy\utils\python.py”, 第 353 行,在 下一个 返回下一个(self.data)文件“C:\Users\User\Desktop\Personal\DABRA\Scraper_opensports\venv\lib\site-packages\scrapy\core\spidermw.py”, 第 56 行,在 _evaluate_iterable
对于可迭代的 r:文件“C:\Users\User\Desktop\Personal\DABRA\Scraper_opensports\venv\lib\site-packages\scrapy\spidermiddlewares\offsite.py”, 第 29 行,在 process_spider_output 中 对于 x 结果:文件“C:\Users\User\Desktop\Personal\DABRA\Scraper_opensports\venv\lib\site-packages\scrapy\core\spidermw.py”, 第 56 行,在 _evaluate_iterable
对于可迭代的 r:文件“C:\Users\User\Desktop\Personal\DABRA\Scraper_opensports\venv\lib\site-packages\scrapy\spidermiddlewares\referer.py”, 第 342 行,在
return (_set_referer(r) for r in result or ()) File "C:\Users\User\Desktop\Personal\DABRA\Scraper_opensports\venv\lib\site-packages\scrapy\core\spidermw.py", 第 56 行,在 _evaluate_iterable
对于可迭代的 r:文件“C:\Users\User\Desktop\Personal\DABRA\Scraper_opensports\venv\lib\site-packages\scrapy\spidermiddlewares\urllength.py”, 第 40 行,在
return (r for r in result or () if _filter(r)) File "C:\Users\User\Desktop\Personal\DABRA\Scraper_opensports\venv\lib\site-packages\scrapy\core\spidermw.py", 第 56 行,在 _evaluate_iterable
对于可迭代的 r:文件“C:\Users\User\Desktop\Personal\DABRA\Scraper_opensports\venv\lib\site-packages\scrapy\spidermiddlewares\depth.py”,第 58 行,在
return (r for r in result or () if _filter(r)) File "C:\Users\User\Desktop\Personal\DABRA\Scraper_opensports\venv\lib\site-packages\scrapy\core\spidermw.py", 第 56 行,在 evaluate_iterable
对于可迭代的 r:文件“c:\Users\User\Desktop\Personal\DABRA\Scraper_opensports\opensports\opens_sp_copia_solod.py”, 第 16 行,解析中 yield Request(marca, self.parse_paginator) File "C:\Users\User\Desktop\Personal\DABRA\Scraper_opensports\venv\lib\site-packages\scrapy\http\request_init
.py", 第 25 行,在 init 中 self.set_url(url) 文件 "C:\Users\User\Desktop\Personal\DABRA\Scraper_opensports\venv\lib\site-packages\scrapy\http\request_init.py", 第 73 行,在 _set_url raise ValueError(f'Missing scheme in request url: {self._url}') ValueError: Missing scheme in request url: /marca/adidas.html 2022-01-16 03:45:07 [scrapy.core.engine] 信息:关闭蜘蛛 (已完成)2022-01-16 03:45:07 [scrapy.statscollectors] 信息:倾销 Scrapy stats: {'downloader/request_bytes': 232, 'downloader/request_count': 1, 'downloader/request_method_count/GET': 1、'downloader/response_bytes':22711、'downloader/response_count': 1, 'downloader/response_status_count/200': 1, 'elapsed_time_seconds':1.748282,'finish_reason':'完成', 'finish_time': datetime.datetime(2022, 1, 16, 6, 45, 7, 151772), 'httpcompression/response_bytes': 116063, 'httpcompression/response_count': 1, 'log_count/DEBUG': 1, “log_count/ERROR”:1,“log_count/INFO”:10,“log_count/WARNING”:1, 'response_received_count':1,'调度程序/出队':1, “调度程序/出队/内存”:1,“调度程序/入队”:1, '调度程序/排队/内存':1,'spider_exceptions/ValueError':1, 'start_time': datetime.datetime(2022, 1, 16, 6, 45, 5, 403490)}

起初我的 f' url 有问题...我不知道如何连接 url,因为在:

marcas= response.css('#maincontent > div.category-view > div > div.brands-page > table > tbody  td a::attr(href)').getall()

我得到了这种类型的网址(不知道是否可以或我需要 https:// 部分):

'/marca/adidas.html'

我知道这是错误的,但我找不到解决方法...谁能帮帮我?

提前致谢!

【问题讨论】:

  • 错误很清楚,您尝试抓取的 url 在开头没有方案 https 或 http ...在 shell 中打印 url 并使用正确的方案构造 url ...并且错误将消失
  • 是的,我明白了,但我不知道该怎么做!

标签: css web-scraping scrapy href


【解决方案1】:

对于亲戚,您可以使用response.follow 或使用请求只需添加基本网址。

您遇到的其他一些错误:

  1. 分页并不总是有效。
  2. 在函数parse_listings 中你有class 属性而不是href。
  3. 出于某种原因,我的某些网址的状态为 500。

我已经修复了错误 #1 和 #2,您需要弄清楚如何修复错误 #3。

import scrapy
from scrapy import Request
from scrapy.crawler import CrawlerProcess
from datetime import datetime
import datetime


#start_url: https://www.opensports.com.ar/marcas.html
class SolodeportesSpider(scrapy.Spider):
    name = 'solodeportes'
    start_urls = ['https://www.opensports.com.ar/marcas.html']
    custom_settings = {
        'FEED_URI': 'opensports_' + f'{datetime.datetime.today().strftime("%d-%m-%Y-%H%M%S")}.csv', 'FEED_FORMAT': 'csv',
    }

    #get links of dif. brands
    def parse(self, response):
        marcas= response.css('#maincontent > div.category-view > div > div.brands-page > table > tbody  td a::attr(href)').getall()
        for marca in marcas:
            yield response.follow(url=marca, callback=self.parse_paginator)

    #get total number of pages of the brand And request all pages from 1 to  total number of products
    def parse_paginator(self, response):
        yield scrapy.Request(url=response.url, callback=self.parse_listings, dont_filter=True)
        next_page = response.xpath('//a[contains(@class, "next")]/@href').get()
        if next_page:
            yield scrapy.Request(url=next_page, callback=self.parse_paginator)

    #Links list to click to get the articles detail
    def parse_listings(self, response):
        all_listings = response.css('a.product-item-link::attr(href)').getall()
        for url in all_listings:
            yield Request(url, self.detail_page)

    #url--Article-- Needed data
    def detail_page(self, response):
        yield {
            'Nombre_Articulo': response.css('h1.page-title span::text').get(),
            'Precio_Articulo': response.css('span.price::text').get(),
            'Sku_Articulo': response.css('td[data-th="SKU"]::text').get(),
            'Tipo_Producto': response.css('td[data-th="Disciplina"]::text').get(),
            'Item_url': response.url
        }

【讨论】:

  • ohhhh 超级用户,这太有帮助了!!。我真的很感谢你的帮助。我没有注意到错误。对我来说这是一个新世界,我会尽力修复#3。如果得到解决方案,我会发布!非常感谢!
  • @MaximilianoVazquez 没问题。祝你好运!
猜你喜欢
  • 2017-03-31
  • 1970-01-01
  • 2016-05-12
  • 1970-01-01
  • 2022-10-25
  • 2014-05-18
  • 2022-12-01
  • 2020-11-10
相关资源
最近更新 更多