Python中Scrapy框架的请求问题如何解决?

我在写爬虫,遇到一个问题。大概是这样的,我先请求首页,然后拿到分页总数,然后按分页请求每一页的数据,但是分页的数据,有时候会请求不到,那么我想,请求不到吧 我再写个方法再去请求一次,再请求不到就算了。但是分页请求即使请求不到数据,但是也不会再去请求下一次。不知道为啥。

爬虫内代码为:

   def parse(self, response):
        while pageNow < pageTotal:

                yield scrapy.Request(url, self.parseNext)

def parseNext(self, response):

        #如果失败了
        yield scrapy.Request(url, self,parseData)

def parseData(self, response):

        #问题是不走到这个方法里面来


Python中Scrapy框架的请求问题如何解决?

9 回复

写个中间件


在Scrapy里处理请求问题,核心是理解它的异步架构。最常见的问题包括请求被过滤、请求头缺失、代理设置不当或回调函数没触发。

这里是一个完整的爬虫示例,覆盖了常见配置和错误处理:

import scrapy
from scrapy.http import Request
from scrapy.exceptions import CloseSpider

class ExampleSpider(scrapy.Spider):
    name = 'example'
    
    # 1. 起始URL配置
    start_urls = ['http://example.com/page1']
    
    # 2. 自定义设置(优先级高于settings.py)
    custom_settings = {
        'USER_AGENT': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
        'CONCURRENT_REQUESTS': 16,
        'DOWNLOAD_DELAY': 0.5,
        'RETRY_TIMES': 3,
        'COOKIES_ENABLED': False,
    }
    
    def start_requests(self):
        """自定义起始请求"""
        for url in self.start_urls:
            yield Request(
                url,
                callback=self.parse,
                errback=self.error_handler,  # 错误回调
                meta={'proxy': 'http://proxy.example.com:8080'},  # 代理设置
                headers={'Referer': 'http://example.com'},
                dont_filter=True  # 不过滤重复请求
            )
    
    def parse(self, response):
        """成功回调"""
        if response.status != 200:
            self.logger.warning(f'非200响应: {response.url}')
            return
        
        # 提取数据
        title = response.css('h1::text').get()
        
        # 生成新请求
        next_page = response.css('a.next::attr(href)').get()
        if next_page:
            yield response.follow(
                next_page,
                callback=self.parse,
                errback=self.error_handler
            )
    
    def error_handler(self, failure):
        """错误处理"""
        request = failure.request
        self.logger.error(f'请求失败: {request.url}, 错误: {failure.value}')
        
        # 可在此重试逻辑
        if failure.check(scrapy.exceptions.TimeoutError):
            self.logger.warning(f'超时重试: {request.url}')

# 运行爬虫的命令行指令
# scrapy runspider example.py -o output.json

关键点:

  1. 请求去重:默认开启,用dont_filter=True关闭
  2. 错误处理:必须设置errback回调
  3. 请求头:在Request()custom_settings中设置
  4. 代理:通过meta={'proxy': ...}设置
  5. 回调链:确保每个请求都有正确的callback

调试时用scrapy shell <url>测试请求,查看响应头和状态码。如果遇到403/429,需要调整请求频率或添加更真实的请求头。

总结:配好请求头、代理和错误处理基本能解决大部分问题。

同样的请求第二次被过滤掉了?加 dont-filte

中间件 download middle 是写了的,但是,download middle 我是用来使用代理的。

好的 谢谢 我来试试

谢谢 确实是这样的

用 chrome headless

什么?

参考 scrapy 内置的 RetryMiddleware 和 DownloadTimeoutMiddleware

回到顶部