You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python网页爬虫无限循环问题排查(附代码)

爬虫无限循环问题排查与修复(针对books.toscrape.com)

核心问题分析

你的爬虫出现无限循环、重复爬取的原因主要有三点:

1. 分类index_number逻辑完全错误

网站每个分类的URL后缀是固定的(比如Travel分类是travel_2,Mystery是mystery_3),index_number是分类的序号,从2开始依次对应每个分类。但你的代码在每个分类循环里都把index_number初始化为2,还试图在while的else块递增——而while循环只有遇到break才会退出,else块永远不会执行,导致所有分类都用index_number=2(即Travel分类的URL)爬取,重复爬同一个分类的内容。

2. 分页请求失败时的错误处理

当请求分页URL(比如page-2.html)返回非200时,你会重新请求该分类的基础页面(index.html),而基础页面必然存在书籍数据,导致if not books:永远触发不了break,page_number持续递增,每次都重复爬取该分类的第一页,形成无限循环。

3. 分页判断逻辑缺失

没有判断当前分类是否存在下一页,只是盲目递增page_number,导致无效请求后触发重复爬取。

修复方案与代码

关键修改点

  • 给每个分类匹配正确的index_number:根据分类在列表中的顺序,从2开始依次赋值
  • 修正分页逻辑:请求分页URL失败时直接退出循环,不再回退到基础页面
  • 先爬取分类基础页面,再判断是否存在分页按钮,决定是否继续爬取后续页面

修复后的完整代码

from bs4 import BeautifulSoup
import requests

home_url = "http://books.toscrape.com/index.html"
base_url = "http://books.toscrape.com/catalogue/category/books/{}_{}/index.html"
page_url_format = "http://books.toscrape.com/catalogue/category/books/{}_{}/page-{}.html"

response = requests.get(home_url)
response.encoding = response.apparent_encoding

soup = BeautifulSoup(response.text, "lxml")
ul_element = soup.find("ul", class_="nav nav-list")
genres = ul_element.find_all("a")
list_genres = []
main_genres = []

for genre in genres:
    text = genre.text.strip()
    list_genres.append(text)
del list_genres[0]  # 移除第一个"Books"全部分类

# 给每个分类匹配正确的index_number(从2开始)
genre_index_map = {}
for idx, genre_name in enumerate(list_genres):
    formatted_genre = genre_name.replace(" ", "-").lower()
    genre_index_map[formatted_genre] = idx + 2  # index从2开始对应第一个分类Travel

with open("genre.txt", "w", encoding="utf-8") as file:
    for genre, index_number in genre_index_map.items():
        page_number = 1
        while True:
            # 先构建当前页码的URL
            if page_number == 1:
                current_url = base_url.format(genre, index_number)
            else:
                current_url = page_url_format.format(genre, index_number, page_number)
            
            response_page = requests.get(current_url)
            response_page.encoding = response_page.apparent_encoding
            
            # 请求失败直接退出循环,说明该页码不存在
            if response_page.status_code != 200:
                break
            
            soup = BeautifulSoup(response_page.text, "lxml")
            books = soup.find_all("li", class_="col-xs-6 col-sm-4 col-md-3 col-lg-3")
            
            # 没有书籍也退出
            if not books:
                break
            
            # 解析书籍信息
            for book in books:
                cost_element = book.find("p", class_="price_color")
                cost = cost_element.text.strip()

                h3_tag = book.find("h3")
                title_element = h3_tag.find("a")
                title = title_element["title"]

                stock_availability_element = book.find("p", class_="instock availability")
                stock_availability = stock_availability_element.text.strip()

                class_star = book.find("p", class_=True)
                p_class = class_star["class"]
                stars = next((star for star in ["One", "Two", "Three", "Four", "Five"] if star == p_class[1]), "Unknown")

                file.write(f"Title: {title}\n")
                file.write(f"Price: {cost}\n")
                file.write(f"Stock Availability: {stock_availability}\n")
                file.write(f"Stars: {stars}\n")
                file.write("\n")
            
            # 判断是否存在下一页
            next_page = soup.find("li", class_="next")
            if not next_page:
                break
            
            page_number += 1

print("爬取完成")

修复说明

  1. genre_index_map:通过枚举分类列表的索引,给每个分类分配正确的index_number,确保每个分类使用对应的URL
  2. 分页判断:每次爬取后检查页面是否有next按钮,没有则说明没有更多页面,直接退出循环
  3. 请求失败处理:请求分页URL返回非200时直接退出,避免重复爬取基础页面
  4. 优化解析逻辑:用next()简化星级判断,避免不必要的循环;统一处理文本strip,减少冗余

内容的提问来源于stack exchange,提问作者Nouri_Dawalibi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 10:27:05