
本文旨在解决使用beautifulsoup进行网页抓取时,因选择器不准确或数据提取方式不当导致返回空列表的常见问题。通过分析错误示例,我们将重点介绍如何利用css选择器进行更精确的元素定位,并采用迭代父元素、逐个提取子元素的高效策略,辅以`.get_text()`方法确保文本内容的正确获取,从而构建稳定可靠的网页数据抓取程序。
在使用Python的requests和BeautifulSoup库进行网页数据抓取时,一个常见的困扰是程序最终输出一个空列表。这通常不是因为网络请求失败(尽管这也是一个需要检查的因素),而是因为BeautifulSoup未能根据我们提供的选择器找到目标元素。
以以下代码片段为例,它尝试从inshorts.com抓取新闻标题和内容:
import requests
from bs4 import BeautifulSoup
url = 'https://inshorts.com/en/read/technology'
news_data = []
news_category = url.split('/')[-1]
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36'}
data = requests.get(url, headers=headers)
if data.status_code == 200:
soup = BeautifulSoup(data.content, 'html.parser')
# 原始代码中的选择器
headlines = soup.find('div', class_=['news-card-title', 'news-right-box'])
articles = soup.find('div', class_=['news-card-content', 'news-right-box'])
if headlines and articles and len(headlines) == len(articles):
news_articles = [
{
'news_headline': headline.find_all('span', attrs={'itemprop': 'headline'}).string,
'news_article': article.find_all('div', attrs={'itemprop': 'articleBody'}).string,
'news_category': news_category
}
for headline, article in zip(headlines, articles)
]
news_data.extend(news_articles)
print(news_data)这段代码返回空列表的主要原因在于其选择器存在问题。soup.find('div', class_=['news-card-title', 'news-right-box'])和soup.find('div', class_=['news-card-content', 'news-right-box'])这两个语句很可能返回None。find()方法只返回匹配的第一个元素,并且在处理class_参数时,传入列表通常表示匹配所有这些类,而不是匹配其中任意一个。更重要的是,如果选择器不准确,find()将直接返回None,导致后续对headlines或articles进行操作时引发错误,或者在if headlines and articles条件判断时直接失败,最终导致news_data保持为空。此外,即使元素被找到,find_all(...).string也可能无法正确提取文本,因为find_all返回的是一个列表,即使只有一个元素,也需要进一步处理,且.string属性仅适用于只有一个子节点的标签。
为了解决上述问题,我们需要采用更精确的选择器和更健壮的数据提取逻辑。关键在于:
以下是优化后的代码,展示了如何应用这些策略:
import requests
from bs4 import BeautifulSoup
url = 'https://inshorts.com/en/read/technology'
news_data = []
news_category = url.split('/')[-1]
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36'}
data = requests.get(url, headers=headers)
if data.status_code == 200:
soup = BeautifulSoup(data.content, 'html.parser')
# 使用CSS选择器定位每个新闻文章的父级容器
# 经过网页检查,发现每个新闻文章都由一个具有特定itemtype属性的div包裹
for article in soup.select('[itemtype="http://schema.org/NewsArticle"]'):
# 在每个article容器内,使用select_one定位标题和文章内容
headline_element = article.select_one('[itemprop="headline"]')
article_body_element = article.select_one('[itemprop="articleBody"]')
# 检查元素是否存在,并使用.get_text()提取文本
news_headline = headline_element.get_text(strip=True) if headline_element else "N/A"
news_article = article_body_element.get_text(strip=True) if article_body_element else "N/A"
news_data.append(
{
'news_headline': news_headline,
'news_article': news_article,
'news_category': news_category
}
)
print(news_data)代码解析:
当BeautifulSoup返回空列表时,通常意味着您的选择器未能准确匹配目标元素。通过采用更精确的CSS选择器(如select()和select_one()),定位包含完整数据单元的父级容器,并在其内部进行迭代和局部提取,结合使用.get_text()方法,可以显著提高网页抓取程序的稳定性和准确性。始终牢记,深入理解目标网页的HTML结构是编写高效、健壮爬虫的关键。
以上就是解决BeautifulSoup网页抓取空列表问题:优化选择器与数据提取策略的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号