Scrapy爬取亚马逊时如何正确提取商品详情页URL
提取失败核心原因
你拿不到商品详情页URL是CSS选择器写法存在3个硬错误,另有一处逻辑bug:
- 类名缺少匹配前缀:CSS选择器里所有类名前必须加
.才会按类名匹配,你写的a-link-normal等类名没加前缀,选择器会把它当成自定义标签名匹配,根本选不到目标元素 - 多类名选择器误加空格:同一个标签的多个类名要连写,中间不能加空格,加空格会被识别为后代选择器,也就是匹配前一个标签内部嵌套的子标签,匹配层级完全错误
- 属性提取语法错误:href是标签原生属性,提取属性值必须用
::attr(href)语法,你之前尝试的::href是无效的伪类写法,无法被解析器识别 - 逻辑bug:你把
BigItem()实例写在了for循环外面,循环过程中会反复修改同一个item对象,极易出现数据串扰、字段覆盖的问题
修正后的可运行代码
from urllib.parse import urljoin import scrapy # 假设你的BigItem已经提前定义好 class YourSpider(scrapy.Spider): # 省略你原有的spider name、start_urls等配置 def parse(self, response): all_boxes = response.css('.s-widget-spacing-small > .sg-col-inner') for boxes in all_boxes: # item实例化必须放在循环内部,每轮循环生成新的独立item items = BigItem() # 原有字段的css选择器可以合并写法,不用拆成两次css调用 name = boxes.css('.s-link-style .a-text-normal::text').getall() author = boxes.css('.a-color-secondary .a-size-base:nth-child(2)::text').getall() price = boxes.css('.s-price-instructions-style .a-price-whole::text').getall() imagelink = boxes.css('.s-image::attr(src)').getall() rating = boxes.css('.a-spacing-top-small .aok-align-bottom::text').getall() valuation = boxes.css('.a-spacing-top-small .s-link-style .s-underline-text::text').getall() # 修正链接选择器:a标签后接连写的带.前缀的类名,用正确的attr语法取href link = boxes.css('a.a-link-normal.s-underline-text.s-underline-link-text.s-link-style.a-text-normal::attr(href)').get() # 亚马逊返回的是/dp/xxx格式的相对路径,拼接成完整可访问的URL if link: link = urljoin(response.url, link) items['name'] = name items['author'] = author items['price'] = price items['imagelink'] = imagelink items['rating'] = rating items['valuation'] = valuation items['link'] = link yield items
优化提示
- 提取单个字段值的时候优先用
get(),提取多个值用getall(),替代老版本的extract()/extract_first(),语义更清晰,返回值格式更可控 - 如果上面的链接选择器因为亚马逊页面class名微调失效,可以直接用更稳定的兜底选择器:
boxes.css('h2 a::attr(href)').get(),亚马逊搜索结果的商品标题固定嵌套在h2标签下的a标签里,这个结构很少变动,适配性更强 - 爬取亚马逊时建议在请求头里加正常的浏览器UA,同时控制请求频率,避免被反爬拦截
目标链接在页面中的位置参考:
内容的提问来源于stack exchange,提问作者Hamsi Tava
相关产品推荐
相关产品推荐

