mwt20201010 2024-02-11 23:55 采纳率: 100%
浏览 6
已结题

scrapy中yield scrapy.Request()后数据丢失


import scrapy
from douban.items import DoubanItem
import scrapy.utils.misc
import scrapy.core.scraper

def warn_on_generator_with_return_value_stub(spider, callable):
    pass

scrapy.utils.misc.warn_on_generator_with_return_value = warn_on_generator_with_return_value_stub
scrapy.core.scraper.warn_on_generator_with_return_value = warn_on_generator_with_return_value_stub


class DbchuancanSpider(scrapy.Spider):
    name = "dbchuancan"
    # allowed_domains = ["www.xxx.com"]
    start_urls = ["https://movie.douban.com/top250?start=0&filter="]
    def page_detail(self,response):
        item = response.meta['item']
        score = response.xpath('//*[@id="interest_sectl"]/div[1]/div[2]/strong/text()')[0].extract()
        # print(score)
        item['score'] = score
        # print(item)
        yield item

    def parse(self, response):
        div_list = response.xpath('//div[@class="hd"]')
        for div in div_list:
            item = DoubanItem()
            title = div.xpath('./a/span[1]/text()')[0].extract()
            item['title'] = title
            detail_url = div.xpath('./a/@href')[0].extract()
            yield scrapy.Request(url=detail_url,callback=self.page_detail,meta={'item':item})
            # print(title,detail_url)

爬取豆瓣电影top250电影名及评分,经检查在parse函数中print时能输出25条信息,但是到了page_detail函数中print时数据量就变少了很多,3~6条信息,而且输出的基本都是那25条信息中靠后的信息,不太清楚怎么回事,请大家解惑
以下是日志信息:


(venv) PS C:\python_learning\douban> scrapy crawl dbchuancan
2024-02-12 00:09:30 [scrapy.utils.log] INFO: Scrapy 2.11.0 started (bot: douban)
2024-02-12 00:09:30 [scrapy.utils.log] INFO: Versions: lxml 5.1.0.0, libxml2 2.10.3, cssselect 1.2.0, parsel 1.8.1, w3lib 2.1.2, Twisted 22.10.0, Python 3.11.4 (tags/v3.11.4:d2340ef, Jun  7 2023, 05:45:37) [MSC v.1934 64 bit (AMD64)], pyOpenSSL 24.0.0 (OpenSSL 3.2.1 30 Jan 2024), cryptography 42.0.2, Platform Windows-10-10.0.22621-SP0
2024-02-12 00:09:30 [scrapy.addons] INFO: Enabled addons:
[]
2024-02-12 00:09:30 [asyncio] DEBUG: Using selector: SelectSelector
2024-02-12 00:09:30 [scrapy.utils.log] DEBUG: Using reactor: twisted.internet.asyncioreactor.AsyncioSelectorReactor
2024-02-12 00:09:30 [scrapy.utils.log] DEBUG: Using asyncio event loop: asyncio.windows_events._WindowsSelectorEventLoop
2024-02-12 00:09:30 [scrapy.extensions.telnet] INFO: Telnet Password: ef09d2f430b48558
2024-02-12 00:09:30 [scrapy.middleware] INFO: Enabled extensions:
['scrapy.extensions.corestats.CoreStats',
 'scrapy.extensions.telnet.TelnetConsole',
 'scrapy.extensions.logstats.LogStats']
2024-02-12 00:09:30 [scrapy.crawler] INFO: Overridden settings:
{'BOT_NAME': 'douban',
 'FEED_EXPORT_ENCODING': 'utf-8',
 'NEWSPIDER_MODULE': 'douban.spiders',
 'REQUEST_FINGERPRINTER_IMPLEMENTATION': '2.7',
 'SPIDER_MODULES': ['douban.spiders'],
 'TWISTED_REACTOR': 'twisted.internet.asyncioreactor.AsyncioSelectorReactor',
 'USER_AGENT': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 '
               '(KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36'}
2024-02-12 00:09:30 [scrapy.middleware] INFO: Enabled downloader middlewares:
['scrapy.downloadermiddlewares.httpauth.HttpAuthMiddleware',
 'scrapy.downloadermiddlewares.downloadtimeout.DownloadTimeoutMiddleware',
 'scrapy.downloadermiddlewares.defaultheaders.DefaultHeadersMiddleware',
 'scrapy.downloadermiddlewares.useragent.UserAgentMiddleware',
 'scrapy.downloadermiddlewares.retry.RetryMiddleware',
 'scrapy.downloader


  • 写回答

4条回答 默认 最新

  • 专家-赤兔[在线] 全栈领域优质创作者 2024-02-11 23:57
    关注

    引自免费微信小程序:皆我百晓生

    在您的Scrapy爬虫中,数据丢失的问题可能与请求的并发性和Scrapy的默认下载中间件设置有关。从代码来看,parse函数正确地为每个电影详情页生成了新的scrapy.Request,并设置了回调函数为page_detail,同时将item对象通过meta参数传递。

    但是,您提到的现象表明并非所有请求都能成功地被处理和返回结果。以下是几种可能的原因及解决办法:

    1. 并发设置: Scrapy会并发地发送多个请求。如果目标网站对来自同一IP地址或同一用户的请求频率有限制,那么部分请求可能会失败或者没有及时响应。您可以调整CONCURRENT_REQUESTS_PER_DOMAIN设置来限制同一时间向一个域名发起的请求数量。

    2. 下载中间件问题: 检查Scrapy的下载中间件是否影响了请求的执行。默认情况下,某些中间件如重试中间件可能会导致部分请求重试而未在第一次尝试时获取到数据。确保下载中间件配置正确无误。

    3. 解析逻辑错误: 虽然在您的代码中未看到明显问题,但确认一下detail_url是否正确生成,并且指向的是有效的电影详情页面。

    4. 调试输出位置: 确保在page_detail方法中yield的item也被正确地处理和存储。如果您只在该方法内部打印输出,而没有实现Item Pipeline或其他持久化操作(如写入文件或数据库),那么即便有数据也看不到实际的完整结果。

    5. 网络延迟或不稳定: 由于网络环境因素,部分请求可能需要更长的时间才能完成。可以在settings.py中适当增加下载延迟(DOWNLOAD_DELAY)以减少服务器压力并提高请求成功率。

    建议进行以下排查步骤:

    • 检查日志:查看Scrapy运行时的日志,查找是否有任何关于请求失败或被过滤掉的信息。
    • 启用跟踪中间件:可以使用Scrapy自带的scrapy.contrib.spidermiddleware.offsite.OffsiteMiddleware中间件来跟踪请求是否成功发出以及响应情况。
    • 增加Item Pipeline:编写一个简单的Item Pipeline来确保每一个yield的item都会被记录下来,便于观察整个流程中的数据流。

    示例Pipeline类:

    # pipelines.py
    class DebugPipeline:
        def process_item(self, item, spider):
            print(f"Processing item: {item}")
            return item
    

    并在settings.py中启用该Pipeline:

    # settings.py
    ITEM_PIPELINES = {
        'your_project.pipelines.DebugPipeline': 100,
    }
    

    最后,请确保根据实际情况更新上述代码,并测试爬虫以定位问题所在。如果仍然无法解决问题,请提供更多详细信息,例如日志内容、项目配置等。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(3条)

报告相同问题?

问题事件

  • 系统已结题 2月20日
  • 已采纳回答 2月12日
  • 修改了问题 2月12日
  • 创建了问题 2月11日

悬赏问题

  • ¥15 mmocr的训练错误,结果全为0
  • ¥15 python的qt5界面
  • ¥15 无线电能传输系统MATLAB仿真问题
  • ¥50 如何用脚本实现输入法的热键设置
  • ¥20 我想使用一些网络协议或者部分协议也行,主要想实现类似于traceroute的一定步长内的路由拓扑功能
  • ¥30 深度学习,前后端连接
  • ¥15 孟德尔随机化结果不一致
  • ¥15 apm2.8飞控罗盘bad health,加速度计校准失败
  • ¥15 求解O-S方程的特征值问题给出边界层布拉休斯平行流的中性曲线
  • ¥15 谁有desed数据集呀