使用Beautiful Soup无法获取全部指定class图片(仅得前5个)
解决Beautiful Soup仅抓取到前5张图片的问题
Hey,我碰到过类似的漫画爬取问题,你的情况大概率不是find_all的锅,而是网站的加载机制或者HTML细节坑到你了,咱们来一步步排查解决:
可能的核心原因
- 动态加载陷阱:很多漫画网站会用JavaScript异步加载后续图片(比如滚动到页面底部才加载第6张及以后),你用
requests获取的只是页面初始HTML,后面的图片标签根本不在这个初始响应里。 - class属性的细微差异:看起来是同一个class,但可能后面的img标签class多了空格分隔的后缀(比如前5张是
manga-img,后面是manga-img lazy-load),或者存在大小写差异,导致精准匹配失效。 - 嵌套节点的隐藏属性:有些网站会把后续图片放在带
display:none这类属性的div里,初始状态下不渲染,虽然requests能拿到HTML,但你可能没注意到这些节点的特殊状态。
针对性解决方案
方案1:处理动态加载内容
如果是JS异步加载,单纯的requests+BeautifulSoup就不够了,得用能执行JavaScript的工具,比如selenium。举个实用的例子:
from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC import os, sys, bs4 target_url = 'https://mangapanda.onl/chapter/' + '-'.join(sys.argv[1:]) os.makedirs('manga', exist_ok=True) # 初始化Chrome浏览器(需要提前下载对应版本的ChromeDriver) driver = webdriver.Chrome() driver.get(target_url) # 等待所有图片加载完成(可根据实际情况调整等待时长和条件) WebDriverWait(driver, 15).until( EC.presence_of_all_elements_located((By.CLASS_NAME, "你的图片class名称")) ) # 获取渲染后的完整页面HTML soup = bs4.BeautifulSoup(driver.page_source, 'html.parser') driver.quit() # 现在再抓取所有目标图片标签 img_tags = soup.find_all('img', class_='你的图片class名称') for idx, img in enumerate(img_tags): img_url = img.get('src') # 这里可以添加下载图片的逻辑,比如用requests保存到本地 print(f"第{idx+1}张图片URL:{img_url}")
方案2:修正class匹配规则
先打印所有img标签的class,看看前后图片的class是否真的一致:
import requests, bs4, sys target_url = 'https://mangapanda.onl/chapter/' + '-'.join(sys.argv[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' } res = requests.get(target_url, headers=headers) res.raise_for_status() soup = bs4.BeautifulSoup(res.text, 'html.parser') # 遍历所有img,打印它们的class属性 for img in soup.find_all('img'): print(f"img标签class:{img.get('class')}")
如果发现后面的img有额外的class后缀,可以用CSS选择器做模糊匹配:
# 匹配class中包含目标关键词的所有img标签 img_tags = soup.select('img[class*="manga-img"]')
方案3:强制遍历所有嵌套节点
虽然find_all默认会递归查找所有子节点,但你可以显式遍历所有div节点,确保不遗漏深层嵌套的图片:
# 遍历页面中所有div,提取其中的目标图片 all_divs = soup.find_all('div') target_imgs = [] for div in all_divs: imgs_in_div = div.find_all('img', class_='你的图片class名称') if imgs_in_div: target_imgs.extend(imgs_in_div) # 去重(避免重复抓取) target_imgs = list({img.get('src'): img for img in target_imgs}.values())
额外实用小贴士
- 用浏览器开发者工具(F12)对比前5张和第6张图片的HTML结构,重点看class、src属性、父节点的差异。
- 爬取时记得加请求头模拟浏览器,避免被网站反爬拦截(上面的代码里已经加了示例header)。
内容的提问来源于stack exchange,提问作者Mr.Magik
相关产品推荐
相关产品推荐

