Python使用requests+BeautifulSoup循环爬取多URL无数据问题排查
问题排查及修复方案
1. 先确认请求是否拿到了正确的页面内容
- 亚马逊有严格的反爬机制,直接不带请求头发送请求大概率会返回403、验证码页面,而非正常的商品搜索页,可以先打印响应状态码和返回的文本前几百个字符确认:
r = requests.get(url) print(r.status_code) print(r.text[:500])
- 修复方案:给请求添加模拟浏览器的headers,示例:
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" } r = requests.get(url, headers=headers)
2. 修复变量名冲突问题
你在循环外定义了存储结果的列表title = [],但后续for循环的迭代变量也命名为for title in firme:,这会直接覆盖列表变量,后续title.append()操作实际是在给循环迭代到的标签元素执行append,而非给目标列表加内容,把迭代变量改名即可,比如改成for item in firme:。
3. 修复列表初始化位置错误
你当前把title = []、desc = []、page = []写在while循环内部,每次翻页都会清空三个列表的内容,就算爬取到数据也只会保留最后一页的结果,把三个列表的初始化移到while循环外面即可。
4. 修正错误的DOM选择逻辑
- 你已经用
firme = zute_soup.findAll('div', {'class': 'brand-follow-tooltip-root'})拿到了所有对应class的div元素,后续循环中又在每个元素内部再次查找相同class的divtitle.findAll('div', {'class': 'brand-follow-tooltip-root'}),这本身就不可能找到匹配元素 - 亚马逊搜索结果页的商品标题不是h1标签,你需要先打开浏览器的开发者工具,重新确认商品标题、品牌信息对应的正确标签和类名,再调整选择器规则。
- 另外调用findAll取第一个元素前先判断是否存在,避免没有匹配元素时报索引错误。
修正后的参考代码
import requests from bs4 import BeautifulSoup base_url = "https://www.amazon.com/s?k=mountain+bikes&ref=nb_sb_noss_" current_page = 1 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" } # 列表初始化移到循环外 title = [] desc = [] page = [] while current_page < 5: print(f"正在爬取第{current_page}页") url = base_url + str(current_page) r = requests.get(url, headers=headers) # 先确认响应正常 if r.status_code != 200: print(f"第{current_page}页请求失败,状态码:{r.status_code}") current_page += 1 continue zute_soup = BeautifulSoup(r.text, 'html.parser') # 此处选择器请根据实际页面结构调整,示例选择商品卡片根元素 firme = zute_soup.findAll('div', {'data-component-type': 's-search-result'}) # 迭代变量改名,避免和列表重名 for item in firme: # 示例取商品标题,类名请自行确认后修改 title_ele = item.find('span', {'class': 'a-size-medium a-color-base a-text-normal'}) # 示例取品牌信息,类名请自行确认后修改 brand_ele = item.find('span', {'class': 'a-size-base-plus a-color-base'}) if not title_ele or not brand_ele: continue title1 = title_ele.text.strip() adresa = brand_ele.text.strip() print(title1, adresa, sep='\n', end='\n\n') page_line = f"{title1}\n{adresa}" title.append(title1) desc.append(adresa) page.append(page_line) current_page += 1
内容的提问来源于stack exchange,提问作者ASH
相关产品推荐
相关产品推荐

