brawellen 2024-07-23 16:15 采纳率: 40%
浏览 1

scrapy+selenium selenium操作出现异常如何返回请求重新执行新的请求

利用selenium+scrapy框架爬虫时,selenium在中间件的检索等自动化操作时遇到了已预知可承受的异常,如搜索不出结果的TimeoutException异常,怎样返回spiders的start_rqeuests继续下一次请求,且检索的内容是由列表构成的,循环遍历检索,出现异常后则跳过列表中该元素检索下一元素。


    def start_requests(self):
        # company_sum_list = get_all_company("昆山市")
        # company_before_list = get_company_before()
        # company_list = [company for company in company_sum_list if company not in company_before_list]
        company_list = ['公司1', '公司2']
        for company in company_list:
            for url in self.start_urls:
                # 第一次请求(使用Selenium中间件)
                yield scrapy.Request(url, callback=self.parse, meta={'use_selenium': True, 'company_name': company})
 
 
    def process_request(self, request, spider):
        if request.meta.get('use_selenium'):
            url = request.url
            company = request.meta.get('company_name')
            try:
                spider.driver.get(url)
                time.sleep(2)
 
                # 模拟搜索操作
                
                # 等待搜索结果加载
                WebDriverWait(spider.driver, 5).until(
                    EC.presence_of_element_located(By.XPATH, "//table[@class='result-table-list']"))
                html = spider.driver.page_source
                # spider.driver.close()
                # 提交搜索结果
                return HtmlResponse(url, body=html, encoding='utf-8', request=request)
            except TimeoutException:
                print(company")
                # 这里怎么返回?

  • 写回答

3条回答 默认 最新

  • 阿里嘎多学长 2024-07-23 16:15
    关注

    以下内容由AIGC及阿里嘎多学长共同生成、有用望采纳:


    在使用 Scrapy 和 Selenium 进行爬虫操作时,处理异常和继续执行请求是一个常见的需求。以下是针对你提出的问题的一些建议和代码示例:

    1. 处理可预知异常: 在 process_request 方法中,你已经使用了 try-except 结构来捕获 TimeoutException。如果需要跳过当前操作,可以在 except 块中添加逻辑来记录异常并继续执行循环。

    2. 继续执行新的请求: 在 except 块中,你不能直接生成一个新的请求并返回到 start_requests 方法,因为 process_request 方法的目的是处理单个请求。但是,你可以记录下异常,并让 start_requests 方法决定是否需要重新生成请求。

    3. 处理循环遍历中的异常: 在 start_requests 方法中,你已经通过 for 循环遍历 company_list。当 process_request 方法捕获到异常时,它应该记录这个异常,但不应该中断整个爬虫的执行。

    4. 正确处理异常并返回: 在 process_request 方法的 except 块中,你可以打印出当前遇到异常的 company 名称,并决定是否需要采取进一步的行动。通常,你不需要在这里生成新的请求,而是应该让 start_requests 方法来处理。

    以下是一个修改后的代码示例,展示了如何在捕获异常时记录异常,并在 start_requests 方法中根据需要重新生成请求:

    class MySpider(scrapy.Spider):
        # ... 其他代码 ...
    
        def start_requests(self):
            company_list = ['公司1', '公司2']
            for company in company_list:
                for url in self.start_urls:
                    yield scrapy.Request(url, callback=self.parse, meta={'use_selenium': True, 'company_name': company})
    
        def process_request(self, request, spider):
            if request.meta.get('use_selenium'):
                try:
                    # ... Selenium 操作 ...
                except TimeoutException as e:
                    print(f"TimeoutException occurred for company: {request.meta['company_name']}")
                    # 可以选择在这里记录日志或者采取其他行动
                    # 但是不要在这里生成新的请求
    
        def parse(self, response):
            # 处理正常响应的逻辑
            pass
    
        def start_requests_on_error(self):
            # 这个方法可以在异常发生后被调用,以重新生成请求
            company_list = ['公司1', '公司2']  # 假设这是从错误中恢复的公司列表
            for company in company_list:
                for url in self.start_urls:
                    yield scrapy.Request(url, callback=self.parse, meta={'use_selenium': True, 'company_name': company})
    
        @classmethod
        def from_crawler(cls, crawler, *args, **kwargs):
            spider = super(MySpider, cls).from_crawler(crawler, *args, **kwargs)
            # 为spider添加一个属性来跟踪是否需要重新生成请求
            spider.needs_restart = False
            return spider
    
        # 这个方法可以在异常发生后调用 start_requests_on_error
        def closed(self, reason):
            if getattr(self, 'needs_restart', False):
                self.crawler.engine.open_spider(self, self.start_requests_on_error)
    

    请注意,这个示例代码只是一个框架,你需要根据你的具体需求来调整和完善它。例如,你可能需要添加逻辑来决定何时调用 start_requests_on_error 方法,以及如何跟踪哪些公司需要重新处理。此外,确保你的异常处理逻辑不会无限循环地重新生成请求。

    评论 编辑记录

报告相同问题?

问题事件

  • 创建了问题 7月23日

悬赏问题

  • ¥15 如何在vue.config.js中读取到public文件夹下window.APP_CONFIG.API_BASE_URL的值
  • ¥50 浦育平台scratch图形化编程
  • ¥20 求这个的原理图 只要原理图
  • ¥15 vue2项目中,如何配置环境,可以在打完包之后修改请求的服务器地址
  • ¥20 微信的店铺小程序如何修改背景图
  • ¥15 UE5.1局部变量对蓝图不可见
  • ¥15 一共有五道问题关于整数幂的运算还有房间号码 还有网络密码的解答?(语言-python)
  • ¥20 sentry如何捕获上传Android ndk 崩溃
  • ¥15 在做logistic回归模型限制性立方条图时候,不能出完整图的困难
  • ¥15 G0系列单片机HAL库中景园gc9307液晶驱动芯片无法使用硬件SPI+DMA驱动,如何解决?