BeautifulSoup批量爬取多页面时随机出现读取失败问题
BeautifulSoup批量爬取多页面时随机出现读取失败问题
看起来你遇到的是典型的反爬机制触发导致的随机失败,和BeautifulSoup本身没啥关系——毕竟你每次都新建了BeautifulSoup实例,换了解析器也没用,说明问题出在请求层面,不是解析环节。
核心原因应该是:你连续爬取60+页后,目标网站检测到了高频的固定请求(相同UA、无间隔),于是返回干扰内容(就是你看到的乱码body)而非正常书籍页面,自然找不到h1标签,最终返回None。
下面给你针对性的解决方案,结合你的代码来改:
1. 给请求加异常处理和状态码检查
你之前的代码直接用requests.get()却没处理请求失败的情况——比如请求超时、网站返回403/503反爬状态码,这时候page.content是异常内容,BeautifulSoup解析出来肯定找不到标题。
修改你的爬取函数:
def scrapSite(URL): # 先准备请求头,后面再优化UA headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:108.0) Gecko/20100101 Firefox/108.0"} try: # 加超时,避免请求挂死在某个页面 page = requests.get(URL, headers=headers, timeout=10) # 主动检查状态码,非200直接抛出异常(比如403反爬、500服务器错误) page.raise_for_status() soup = BeautifulSoup(page.content, "html.parser") title_tag = soup.find('h1', class_='book__title') # 调试用:如果没找到标题,打印页面开头内容,确认网站返回的是什么 if not title_tag: print(f"⚠️ 未找到标题,页面内容预览:{page.text[:500]}...") title = title_tag.text.strip() if title_tag else 'Title not found' return title except Exception as e: print(f"❌ 请求/解析出错 {URL}: {str(e)}") return None
2. 加随机延迟+重试机制,模拟人类浏览节奏
网站大概率是通过请求间隔识别爬虫的——你连续高速爬取60+页,很容易触发频率限制。在每次请求之间加个随机延迟,遇到失败时重试几次,不要直接终止整个爬取:
import time import random counter = 0 books_data = [] for data in books_links: counter += 1 url = data[0] print(f"{url} 序号: {counter}") # 加1-3秒随机延迟,避免被封 time.sleep(random.uniform(1, 3)) # 注意你之前的函数名笔误:scrapSite2应该是scrapSite吧? values = scrapSite(url) # 处理返回空的情况,优先重试而非直接终止 if values is None or values == 'Title not found': print(f"⚠️ Values niestety none dla: {url} numer {counter}") # 重试机制:最多重试3次 retry_count = 3 while retry_count > 0 and (values is None or values == 'Title not found'): print(f"🔄 重试第 {4 - retry_count} 次 {url}") time.sleep(random.uniform(2, 4)) # 重试间隔长一点,降低被封概率 values = scrapSite(url) retry_count -= 1 if values is None or values == 'Title not found': print(f"❌ 重试失败,跳过 {url}") continue # 跳过当前页面,继续爬下一个,不要直接break终止整个循环 books_data.append(values)
3. 丰富请求头,避免被识别为固定爬虫
你现在用的是固定UA,网站很容易追踪到这个固定标识的高频请求。可以准备一组不同浏览器的UA,每次请求随机选一个:
# 定义一组不同设备/浏览器的UA ua_list = [ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36", "Mozilla/5.0 (Macintosh; Intel Mac OS X 14_0) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 Safari/605.1.15", "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/118.0" ] # 修改scrapSite函数里的headers部分,每次随机选UA def scrapSite(URL): headers = {"User-Agent": random.choice(ua_list)} try: page = requests.get(URL, headers=headers, timeout=10) page.raise_for_status() soup = BeautifulSoup(page.content, "html.parser") title_tag = soup.find('h1', class_='book__title') if not title_tag: print(f"⚠️ 未找到标题,页面内容预览:{page.text[:500]}...") title = title_tag.text.strip() if title_tag else 'Title not found' return title except Exception as e: print(f"❌ 请求/解析出错 {URL}: {str(e)}") return None
如果嫌维护UA列表麻烦,也可以用fake_useragent库(先执行pip install fake_useragent安装),它会自动获取最新的UA:
from fake_useragent import UserAgent ua = UserAgent() headers = {"User-Agent": ua.random}
为什么换解析器没用?
因为问题根本不在解析器——当网站返回的是干扰内容(乱码、403反爬页面、验证码页面),不管用什么解析器,都找不到你要的h1标签,所以换解析器解决不了问题,核心是要绕过网站的反爬限制。
内容来源于stack exchange
相关产品推荐
相关产品推荐

