使用scrapy-playwright爬取Amazon ASIN出现部分值缺失求助
解决Scrapy-Playwright爬取亚马逊ASIN部分缺失的问题
问题原因分析
- 等待条件不可靠:你用
div[data-asin]:nth-child(23)作为等待结束的标志,亚马逊搜索页的元素数量、排序会动态变化,这个选择器无法保证所有懒加载元素都已加载完成,导致部分ASIN还没渲染就开始解析。 - 单次滚动不充分:亚马逊商品列表采用懒加载模式,单次滚动到页面底部可能无法触发所有后续商品的加载,尤其是网络较慢时,新元素还没加载完成就停止等待了。
修复方案
方案1:优化等待与滚动逻辑
把固定的第23个元素等待,改为循环滚动+等待新元素加载,直到没有更多内容可加载:
def start_requests(self): url = 'https://www.amazon.com/s?k=laptop&crid=3HPDQBP5QI5QM&sprefix=lap%2Caps%2C672&ref=nb_sb_ss_ts-doa-p_1_3' yield scrapy.Request(url, meta=dict( playwright=True, playwright_include_page=True, playwright_page_methods=[ # 等待初始商品加载完成 PageMethod('wait_for_selector', 'div[data-asin]'), # 循环滚动加载所有内容 PageMethod("evaluate", """ async function scrollToLoadAll() { let lastHeight = document.body.scrollHeight; while (true) { window.scrollTo(0, document.body.scrollHeight); // 等待2秒让新内容加载 await new Promise(resolve => setTimeout(resolve, 2000)); let newHeight = document.body.scrollHeight; if (newHeight === lastHeight) break; lastHeight = newHeight; } } scrollToLoadAll(); """), # 等待最后一个商品元素加载完成 PageMethod('wait_for_selector', 'div[data-asin]:last-child') ], errback=self.errback ))
方案2:直接通过Playwright页面获取元素
部分情况下Scrapy的response无法完全同步Playwright渲染后的最新DOM,直接用Playwright API获取元素更可靠:
async def parse(self, response): page = response.meta["playwright_page"] # 从页面中直接获取所有带data-asin属性的div products = await page.query_selector_all('div[data-asin]') for product in products: asin = await product.get_attribute('data-asin') if asin: # 过滤空ASIN的占位div yield {"asin": asin} await page.close()
额外注意事项
- 亚马逊有反爬机制,建议添加随机延迟、更换User-Agent,避免被限制访问。
- 页面中部分
div[data-asin]可能是空值(比如占位元素),解析时记得过滤这类无效值。
内容的提问来源于stack exchange,提问作者jesan Ahmed
相关产品推荐
相关产品推荐

