如何使用BeautifulSoup提取标签内容 爬取亚马逊畅销榜问题求助
问题1:select方法路径为空的原因
.select()本身没有路径长度限制,是你的CSS选择器写法错误:
多个类名绑定在同一个元素上时,CSS选择器需要用.拼接类名,不能用空格。你写的div.a-section a-spacing-none aok-relative会被识别成「找div.a-section的后代里标签叫a-spacing-none的元素,再找它的后代里叫aok-relative的元素」,自然找不到结果。正确写法应该是:
container = page.select('li.zg-item-immersion > span.a-list-item > div.a-section.a-spacing-none.aok-relative' )
问题2:代码时好时坏的原因
和网络连接无关,是亚马逊的反爬机制拦截了你的请求。你直接用默认参数的requests.get()发送请求,请求头里没有User-Agent,亚马逊会直接判定为爬虫请求,返回验证码页面或者错误响应,你拿到的内容根本不是正常的商品榜单页,所以解析出来的结果自然是空。只有极少数情况可能漏过拦截,才能拿到正常内容。
解决方法是发送请求时带上模拟浏览器的请求头,至少要加User-Agent,同时做响应状态校验:
headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36" } resp = requests.get(url, headers=headers) # 确认请求成功再解析 if resp.status_code == 200: page = BeautifulSoup(resp.content, 'lxml')
问题3:索引越界报错的原因
存在两个错误:
- 当请求被反爬拦截时,
containers的长度根本不是50,甚至可能为0,你强行遍历range(50)去取下标必然越界。 - 你的
ranking变量初始化错误:你一开始直接把它赋值成了单个排名的字符串,后面直接调用append方法本身就会报错,就算没有越界也跑不通。
正确写法是先初始化ranking为空列表,直接遍历containers本身,不要写死长度,同时加字段存在性判断:
ranking = [] containers = page.select('li.zg-item-immersion > span.a-list-item') for item in containers: rank_span = item.find("span", class_="zg-badge-text") if rank_span: ranking.append(rank_span.text[1:])
爬虫学习实用建议
- 解析页面前先校验响应内容:不要拿到响应就直接解析,先判断状态码是否正常,也可以简单搜索响应内容里是否存在你要找的特征字符串(比如zg-badge-text),确认拿到的是目标页面再继续处理,避免做无用功。
- 写选择器优先选稳定标识:尽量选择带业务含义的、唯一的类名作为定位依据,不要写过长的嵌套路径,路径越短、依赖的层级越少,抗页面结构变化的能力越强。
- 做好异常判断:所有定位元素的操作之后都先判断返回值是否为None,不要直接调用.text之类的属性,碰到单个商品缺字段的情况就直接报错中断。
- 反爬处理前置:爬主流大站时,首先要处理请求头、Cookie、代理这些基础反爬措施,大部分情况下解析不到内容都不是选择器的问题,是你根本没拿到正常的页面内容。
- 多对比差异:如果选择器确认写对了还是找不到内容,就把你拿到的HTML存成本地文件,和浏览器里看到的页面结构做对比,就能快速发现是内容不对还是选择器写错了。
内容的提问来源于stack exchange,提问作者DJ-coding
相关产品推荐
相关产品推荐

