2025年08月01日/ 浏览 4
“又是个空数组!”——这可能是许多Scrapy开发者最不愿见到的调试信息。网页抓取过程中返回空数组是爬虫开发中最常见也最令人沮丧的问题之一。当我第一次遇到这个问题时,花了整整两天时间才找到原因,而解决方案竟然如此简单。
空数组问题通常源于以下几个核心原因:
python
response.xpath(‘//div[@class=”product-name”]/text()’).extract() # 返回[]
response.xpath(‘//div[contains(@class, “product-name”)]/text()’).extract()
实用技巧:在Scrapy shell中实时测试选择器:
bash
scrapy shell "https://example.com"
python
print(response.text) # 查看实际获取的HTML
print(response.status) # 确认返回状态码
我曾遇到一个案例,看似简单的选择器却返回空数组,原来是因为网站返回了403状态码,而我没有检查响应状态。
现代网站大量使用JavaScript动态加载内容,传统爬虫无法直接获取这些数据。解决方案包括:
python
import scrapy
from scrapy_splash import SplashRequest
class MySpider(scrapy.Spider):
def start_requests(self):
yield SplashRequest(
url=’https://example.com’,
callback=self.parse,
args={‘wait’: 2} # 等待JS执行
)
网站的反爬策略可能导致返回空内容。应对措施:
设置合理headers:
python
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
'Accept-Language': 'en-US,en;q=0.9'
}
使用代理和延迟:
python
custom_settings = {
'DOWNLOAD_DELAY': 2,
'PROXY_LIST': ['http://proxy1:port', 'http://proxy2:port']
}
处理cookies:
python
yield scrapy.Request(
url,
cookies={'session_id': 'value'},
callback=self.parse
)
python
name = response.xpath('//h1/text()').extract_first() or \
response.xpath('//title/text()').extract_first() or \
response.xpath('//meta[@property="og:title"]/@content').extract_first()
python
def parse(self, response):
if not response.xpath('//div[@class="content"]'):
self.logger.warning(f'Empty content at {response.url}')
yield scrapy.Request(response.url, dont_filter=True, callback=self.parse)
我曾负责一个电商价格监控项目,最初爬虫返回空数组。经过排查发现:
最终解决方案:
python
def parse(self, response):
# 使用包含class名的选择器
products = response.xpath('//div[contains(@class, "prod_") and contains(@class, "_name")]')
if not products:
# 尝试直接调用API
api_url = f"https://api.example.com/products?page={page}"
yield scrapy.Request(api_url, headers={'Referer': response.url})
解决Scrapy空数组问题的过程,实际上是对网页结构、网络协议和反爬机制深入理解的过程。每次解决这类问题,都能显著提升你的爬虫开发能力。记住,当选择器返回空数组时,不要慌张——系统地检查请求、响应和选择器,问题总会迎刃而解。
最后建议:建立一个爬虫调试清单,将常见问题和解法记录下来,这会大幅提高你未来解决类似问题的效率。