BeautifulSoup 是 2000 年及以后的产物:2020 年的网页抓取 1. 无依赖项 2. 内置电池 4. 从原型设计到生产 5. 符合 PEP 561 6. 自动格式化 7. 速度 8. 部分匹配 9. 无债务 10. 开放(且友好)!

2025-06-09

BeautifulSoup 已过时:2020 年的网络抓取

1. 无依赖

2. 包含电池

4. 从原型设计到生产

5. 符合 PEP 561

6.自动格式化

7.速度

8.部分匹配

9. 无债一身轻

10.开放(且友好)!

BeautifulSoup ( bs4) 创建于十五年前,自那时起就一直是网络数据抓取的标准bs4。但现在是时候推出一些新东西了,因为它已经过时了

在这篇文章中,我们将通过抓取这篇文章的部分内容来探讨为什么西班牙凉菜汤是网络抓取的未来!

1. 无依赖

gazpacho在命令行安装:

pip install gazpacho 
Enter fullscreen mode Exit fullscreen mode

没有额外的依赖:

pip freeze
# gazpacho==1.1
Enter fullscreen mode Exit fullscreen mode

相比之下,与bs4打包在一起。我不会告诉你如何编写软件,但最小化依赖关系通常是一个好主意……soupsievelxml

2. 包含电池

可以使用以下命令获取并解析此博客文章的 html Soup.get

from gazpacho import Soup

url = "https://dev.to/maxhumber/beautifulsoup-is-so-2000-and-late-web-scraping-in-2020-2528"
soup = Soup.get(url)
Enter fullscreen mode Exit fullscreen mode

不幸的是,你需要requestsbs4同样的事情:

import requests
from bs4 import BeautifulSoup

url = "https://dev.to/maxhumber/beautifulsoup-is-so-2000-and-late-web-scraping-in-2020-2528"
html = requests.get(url).text
bsoup = BeautifulSoup(html)
Enter fullscreen mode Exit fullscreen mode

3.find简单

bs4简直是庞然大物。每个对象都绑定了184 个BeautifulSoup方法和属性。这让人很难知道该用什么,以及何时该用:

len(dir(BeautifulSoup()))
# 184
Enter fullscreen mode Exit fullscreen mode

相比之下,Soup中的对象gazpacho很简单;只有七种方法和属性需要跟踪:

[method for method in dir(Soup())]
# ['attrs', 'find', 'get', 'html', 'strip', 'tag', 'text']
Enter fullscreen mode Exit fullscreen mode

查看该列表可以清楚地看出,例如,要找到该帖子的标题(嵌套在h1标签内),我们需要使用.find

soup.find('h1')
Enter fullscreen mode Exit fullscreen mode

4. 从原型设计到生产

gazpacho非常适合原型设计,甚至更适合生产环境。默认情况下,如果只找到一个元素,.find则返回一个对象;如果找到多个元素,Soup则返回一个对象列表。Soup

为了在生产中保证和强制返回类型,可以手动设置mode=参数:.find

title = (soup
    .find("header", {'id': 'main-title'}, mode="first")
    .find("h1", mode="all")[0]
    .text
)
Enter fullscreen mode Exit fullscreen mode

相比之下,bs427 种查找方法,它们都返回不同的结果:

[method for method in dir(BeautifulSoup()) if 'find' in method] 
Enter fullscreen mode Exit fullscreen mode

5. 符合 PEP 561

1.1 版开始,gazpacho它符合PEP 561标准。这意味着整个库都是类型化的,并且可以与您的类型化(或标准鸭子/非类型化!)代码库兼容:

help(soup.find)
# Signature:
# soup.find(
#     tag: str,
#     attrs: Union[Dict[str, Any], NoneType] = None,
#     *,
#     partial: bool = True,
#     mode: str = 'automatic',
#     strict: Union[bool, NoneType] = None,
# ) -> Union[List[ForwardRef('Soup')], ForwardRef('Soup'), NoneType]

Enter fullscreen mode Exit fullscreen mode

6.自动格式化

dev.to和这篇文章的 html格式都很好。但如果格式不对:

header = soup.find("div", {'class': 'crayons-article__header__meta'})
html = str(header.find("div", {'class': 'mb-4 spec__tags'}))
bad_html = html.replace("\n", "") # remove new line characters
print(bad_html)
# <div class="mb-4 spec__tags">  <a class="crayons-tag mr-1" href="/t/python" style="background-color:#1E38BB;color:#FFDF5B">    <span class="crayons-tag__prefix">#</span>    python  </a>  <a class="crayons-tag mr-1" href="/t/webscraping" style="background-color:;color:">    <span class="crayons-tag__prefix">#</span>    webscraping  </a>  <a class="crayons-tag mr-1" href="/t/gazpacho" style="background-color:;color:">    <span class="crayons-tag__prefix">#</span>    gazpacho  </a>  <a class="crayons-tag mr-1" href="/t/hacktoberfest" style="background-color:#29161f;color:#ffa368">    <span class="crayons-tag__prefix">#</span>    hacktoberfest  </a></div>
Enter fullscreen mode Exit fullscreen mode

gazpacho能够自动格式化和缩进错误/格式错误的 html:

tags = Soup(bad_html)
Enter fullscreen mode Exit fullscreen mode

让内容更容易阅读:

print(tags)
# <div class="mb-4 spec__tags">
#   <a class="crayons-tag mr-1" href="/t/python" style="background-color:#1E38BB;color:#FFDF5B">
#     <span class="crayons-tag__prefix">#</span>
#         python
#   </a>
#   <a class="crayons-tag mr-1" href="/t/webscraping" style="background-color:;color:">
#     <span class="crayons-tag__prefix">#</span>
#         webscraping
#   </a>
#   <a class="crayons-tag mr-1" href="/t/gazpacho" style="background-color:;color:">
#     <span class="crayons-tag__prefix">#</span>
#         gazpacho
#   </a>
#   <a class="crayons-tag mr-1" href="/t/hacktoberfest" style="background-color:#29161f;color:#ffa368">
#     <span class="crayons-tag__prefix">#</span>
#         hacktoberfest
#   </a>
# </div>
Enter fullscreen mode Exit fullscreen mode

7.速度

gazpacho速度很快。抓取此帖子的标签链接仅需 258 微秒:

%%timeit
tags = Soup(bad_html)
tags = tags.find("a")
tag_links = ["https://dev.to" + tag.attrs['href'] for tag in tags]
# 258 µs ± 10.9 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
Enter fullscreen mode Exit fullscreen mode

bs4做同样的事情却要花几乎两倍的时间:

%%timeit
tags = BeautifulSoup(bad_html)
tags = tags.find_all("a")
tag_links = ["https://dev.to" + tag.attrs['href'] for tag in tags]
# 465 µs ± 2.61 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
Enter fullscreen mode Exit fullscreen mode

8.部分匹配

gazpacho可以部分匹配 HTML 元素属性。例如,此页面的侧边栏显示如下 HTML 代码:

<aside class="crayons-layout__sidebar-right" aria-label="Right sidebar navigation">
Enter fullscreen mode Exit fullscreen mode

并且可以精确匹配:

soup.find("aside", {"class": "crayons-layout__sidebar-right"}, partial=False)
Enter fullscreen mode Exit fullscreen mode

或者部分(默认行为)使用:

sidebar = soup.find("aside", {'aria-label': 'Right sidebar'}, partial=True)

# finding my name
sidebar.find("span", {'class': 'crayons-subtitle-2'}, partial=True).text 
Enter fullscreen mode Exit fullscreen mode

9. 无债一身轻

gazpacho 首先是 Python 3 的Black 版本,使用mypy进行类型转换,sloc 大约为 400。阅读源代码很容易:

import inspect

source = inspect.getsource(Soup.find)
print(source)
Enter fullscreen mode Exit fullscreen mode

并且似乎bs4没有充斥着Python 2 技术债务

10.开放(且友好)!

最重要的是,gazpacho它是开源的,托管在GitHub上(而不是一些笨重的自定义平台)并正在寻找贡献者。

如果你要参加 #hacktoberfest,我们非常欢迎你。有几个未解决的问题需要帮助!

鏂囩珷鏉ユ簮锛�https://dev.to/maxhumer/beautifulsoup-is-so-2000-and-late-web-scraping-in-2020-2528
PREV
使用 Angular 构建可扩展、健壮且类型安全的表单 目录 上下文 介绍演示并理解我们想要构建的示例 反应式表单 反应式表单不是强类型的 #13721 Ngx-Sub-Form:将 Angular 表单分解为多个子组件的实用程序库 总结和收获 有用的链接 发现拼写错误?关注我 您可能还喜欢阅读
NEXT
让我们开发一个二维码生成器,第一部分:基本概念