使用Beautiful Soup在Python中进行网络抓取的指南

Python中的Beautiful Soup库使从网页中提取HTML变得容易。
55 位读者喜欢这篇文章。
Computer screen with files or windows open

Opensource.com

今天我们将讨论如何使用Beautiful Soup库从HTML页面中提取内容。提取后,我们将使用Beautiful Soup将其转换为Python列表或字典。

什么是网络抓取?我为什么需要它?

简单的答案是:并非每个网站都有API来获取内容。您可能想从您最喜欢的烹饪网站获取食谱,或者从旅游博客获取照片。在没有API的情况下,提取HTML,或者 抓取,可能是获取该内容的唯一方法。我将向您展示如何在Python中做到这一点。

并非所有网站都欢迎抓取,有些网站可能会明确禁止抓取。请咨询网站所有者,了解他们是否允许抓取。

如何在Python中抓取网站?

为了使网络抓取在Python中工作,我们将执行三个基本步骤

  1. 使用requests库提取HTML内容。
  2. 分析HTML结构并识别包含我们内容的标签。
  3. 使用Beautiful Soup提取标签并将数据放入Python列表。

安装库

首先,让我们安装我们需要的库。requests库从网站获取HTML内容。Beautiful Soup解析HTML并将其转换为Python对象。要为Python 3安装这些库,请运行

pip3 install requests beautifulsoup4

提取HTML

对于此示例,我将选择抓取本网站的 技术 部分。如果您访问该页面,您将看到一个文章列表,其中包含标题、摘要和发布日期。我们的目标是创建一个包含该信息的文章列表。

技术页面的完整URL是

https://notes.ayushsharma.in/technology

我们可以使用requests从该页面获取HTML内容

#!/usr/bin/python3
import requests

url = 'https://notes.ayushsharma.in/technology'

data = requests.get(url)

print(data.text)

变量data将包含页面的HTML源代码。

从HTML中提取内容

要从data中接收到的HTML中提取我们的数据,我们需要确定哪些标签包含我们需要的内容。

如果您浏览HTML,您会在顶部附近找到此部分

<div class="col">
  <a href="https://open-source.net.cn/2021/08/using-variables-in-jekyll-to-define-custom-content" class="post-card">
    <div class="card">
      <div class="card-body">
        <h5 class="card-title">Using variables in Jekyll to define custom content</h5>
        <small class="card-text text-muted">I recently discovered that Jekyll's config.yml can be used to define custom
          variables for reusing content. I feel like I've been living under a rock all this time. But to err over and
          over again is human.</small>
      </div>
      <div class="card-footer text-end">
        <small class="text-muted">Aug 2021</small>
      </div>
    </div>
  </a>
</div>

这是在整个页面中为每篇文章重复的部分。我们可以看到.card-title包含文章标题,.card-text包含摘要,.card-footer > small包含发布日期。

让我们使用Beautiful Soup提取这些。

#!/usr/bin/python3
import requests
from bs4 import BeautifulSoup
from pprint import pprint

url = 'https://notes.ayushsharma.in/technology'
data = requests.get(url)

my_data = []

html = BeautifulSoup(data.text, 'html.parser')
articles = html.select('a.post-card')

for article in articles:

    title = article.select('.card-title')[0].get_text()
    excerpt = article.select('.card-text')[0].get_text()
    pub_date = article.select('.card-footer small')[0].get_text()

    my_data.append({"title": title, "excerpt": excerpt, "pub_date": pub_date})

pprint(my_data)

上面的代码提取文章并将它们放入my_data变量中。我正在使用pprint来漂亮地打印输出,但您可以在代码中跳过它。将上面的代码保存在名为fetch.py的文件中,然后使用以下命令运行它

python3 fetch.py

如果一切顺利,您应该看到这个

[{'excerpt': "I recently discovered that Jekyll's config.yml can be used to"
"define custom variables for reusing content. I feel like I've"
'been living under a rock all this time. But to err over and over'
'again is human.',
'pub_date': 'Aug 2021',
'title': 'Using variables in Jekyll to define custom content'},
{'excerpt': "In this article, I'll highlight some ideas for Jekyll"
'collections, blog category pages, responsive web-design, and'
'netlify.toml to make static website maintenance a breeze.',
'pub_date': 'Jul 2021',
'title': 'The evolution of ayushsharma.in: Jekyll, Bootstrap, Netlify,'
'static websites, and responsive design.'},
{'excerpt': "These are the top 5 lessons I've learned after 5 years of"
'Terraform-ing.',
'pub_date': 'Jul 2021',
'title': '5 key best practices for sane and usable Terraform setups'},

... (truncated)

这就是全部!在22行代码中,我们构建了一个Python网络抓取器。您可以在我的示例仓库中找到 源代码

结论

有了Python列表中的网站内容,我们现在可以对其进行很酷的操作。我们可以将其作为JSON返回给另一个应用程序,或者使用自定义样式将其转换为HTML。随意复制粘贴上面的代码,并在您最喜欢的网站上进行实验。

玩得开心,继续编码。


本文最初发表在作者的个人博客上,并已获得许可进行改编。

接下来阅读
https://ayushsharma.in
我是一名作家和AWS解决方案架构师。我与初创公司和企业合作,从事软件工程、DevOps、SRE和云架构。我在 https://ayushsharma.in 上写下我的经验。

评论已关闭。

Creative Commons License本作品根据知识共享署名-相同方式共享 4.0 国际许可协议获得许可。
© . All rights reserved.