0

0

解决BeautifulSoup网页抓取空列表问题:优化选择器与数据提取策略

聖光之護

聖光之護

发布时间:2025-10-14 09:40:23

|

374人浏览过

|

来源于php中文网

原创

解决BeautifulSoup网页抓取空列表问题:优化选择器与数据提取策略

本文旨在解决使用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.124124 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属性仅适用于只有一个子节点的标签。

优化选择器与数据提取策略

为了解决上述问题,我们需要采用更精确的选择器和更健壮的数据提取逻辑。关键在于:

住哪API酒店+租车源码包
住哪API酒店+租车源码包

数据本地化解决接口缓存数据无限增加,读取慢的问题,速度极大提升更注重SEO优化优化了系统的SEO,提升网站在搜索引擎的排名,增加网站爆光率搜索框本地化不用远程读取、IFRAME调用,更加容易应用及修改增加天气预报功能页面增加了天气预报功能,丰富内容增加点评和问答页面增加了点评和问答相关页面,增强网站粘性电子地图优化优化了电子地图的加载速度与地图功能酒店列表增加房型读取酒店列表页可以直接展示房型,增

下载
  1. 利用CSS选择器: Beautiful Soup支持强大的CSS选择器,通过select()和select_one()方法,我们可以编写更简洁、更准确的定位规则。
  2. 定位父级容器: 优先找到包含所有目标信息的共同父级容器。这样可以确保我们处理的是一个个完整的数据单元。
  3. 迭代与局部提取: 遍历每个父级容器,然后在该容器的范围内进一步提取其子元素的信息。
  4. 使用.get_text(): 确保正确提取元素的文本内容,避免.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.124124 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)

代码解析:

  1. soup.select('[itemtype="http://schema.org/NewsArticle"]'): 这是核心改进。通过检查目标网页的HTML结构(通常使用浏览器开发者工具),我们发现每篇新闻文章都由一个div标签包裹,该标签具有itemtype="http://schema.org/NewsArticle"属性。这是一个非常精确且稳定的CSS选择器,能够直接选中所有新闻文章的根容器。select()方法会返回一个匹配所有元素的列表。
  2. for article in ...: 我们遍历select()返回的每个article元素,确保我们逐个处理每篇新闻。
  3. article.select_one('[itemprop="headline"]') 和 article.select_one('[itemprop="articleBody"]'): 在每个article容器的内部,我们再次使用select_one()方法来定位新闻标题(itemprop="headline")和文章主体(itemprop="articleBody")。select_one()只返回第一个匹配的元素,适用于我们期望只找到一个标题或一个文章主体的情况。
  4. .get_text(strip=True): 这是提取文本内容的推荐方法。get_text()会获取元素及其所有子元素的可见文本内容,strip=True参数可以去除文本两端的空白字符,使结果更整洁。同时,我们添加了if headline_element else "N/A"这样的检查,以防某些元素确实缺失,增强代码的鲁棒性。

注意事项与最佳实践

  • 审查HTML结构: 在编写任何选择器之前,务必使用浏览器的开发者工具(F12)仔细检查目标网页的HTML结构。理解元素的层级关系、ID、类名、属性等是编写有效选择器的基础。
  • CSS选择器优先: 对于复杂的选择需求,CSS选择器通常比find()和find_all()的组合更强大、更简洁。它们支持ID、类名、属性、子元素、兄弟元素等多种组合方式。
  • 处理动态内容: 如果目标网站使用JavaScript动态加载内容,requests和BeautifulSoup可能无法获取到这些内容。此时,您可能需要考虑使用Selenium等工具来模拟浏览器行为。
  • User-Agent: 在请求头中设置User-Agent是一个良好的实践,可以模拟浏览器访问,降低被网站识别为爬虫并阻止的风险。
  • 错误处理: 始终考虑网络请求失败(data.status_code != 200)和元素未找到(选择器返回None或空列表)的情况,并进行相应的错误处理或默认值设置。
  • 遵守Robots协议: 在进行网页抓取时,请务必查看网站的robots.txt文件,了解网站是否允许爬取以及允许爬取的范围。尊重网站的使用条款。

总结

当BeautifulSoup返回空列表时,通常意味着您的选择器未能准确匹配目标元素。通过采用更精确的CSS选择器(如select()和select_one()),定位包含完整数据单元的父级容器,并在其内部进行迭代和局部提取,结合使用.get_text()方法,可以显著提高网页抓取程序的稳定性和准确性。始终牢记,深入理解目标网页的HTML结构是编写高效、健壮爬虫的关键。

相关专题

更多
python开发工具
python开发工具

php中文网为大家提供各种python开发工具,好的开发工具,可帮助开发者攻克编程学习中的基础障碍,理解每一行源代码在程序执行时在计算机中的过程。php中文网还为大家带来python相关课程以及相关文章等内容,供大家免费下载使用。

765

2023.06.15

python打包成可执行文件
python打包成可执行文件

本专题为大家带来python打包成可执行文件相关的文章,大家可以免费的下载体验。

639

2023.07.20

python能做什么
python能做什么

python能做的有:可用于开发基于控制台的应用程序、多媒体部分开发、用于开发基于Web的应用程序、使用python处理数据、系统编程等等。本专题为大家提供python相关的各种文章、以及下载和课程。

764

2023.07.25

format在python中的用法
format在python中的用法

Python中的format是一种字符串格式化方法,用于将变量或值插入到字符串中的占位符位置。通过format方法,我们可以动态地构建字符串,使其包含不同值。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

619

2023.07.31

python教程
python教程

Python已成为一门网红语言,即使是在非编程开发者当中,也掀起了一股学习的热潮。本专题为大家带来python教程的相关文章,大家可以免费体验学习。

1285

2023.08.03

python环境变量的配置
python环境变量的配置

Python是一种流行的编程语言,被广泛用于软件开发、数据分析和科学计算等领域。在安装Python之后,我们需要配置环境变量,以便在任何位置都能够访问Python的可执行文件。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

549

2023.08.04

python eval
python eval

eval函数是Python中一个非常强大的函数,它可以将字符串作为Python代码进行执行,实现动态编程的效果。然而,由于其潜在的安全风险和性能问题,需要谨慎使用。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

579

2023.08.04

scratch和python区别
scratch和python区别

scratch和python的区别:1、scratch是一种专为初学者设计的图形化编程语言,python是一种文本编程语言;2、scratch使用的是基于积木的编程语法,python采用更加传统的文本编程语法等等。本专题为大家提供scratch和python相关的文章、下载、课程内容,供大家免费下载体验。

709

2023.08.11

PS使用蒙版相关教程
PS使用蒙版相关教程

本专题整合了ps使用蒙版相关教程,阅读专题下面的文章了解更多详细内容。

23

2026.01.19

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Sass 教程
Sass 教程

共14课时 | 0.8万人学习

Bootstrap 5教程
Bootstrap 5教程

共46课时 | 2.9万人学习

CSS教程
CSS教程

共754课时 | 21万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号