📜  使用 BeautifulSoup 在Python实现网页抓取

📅  最后修改于: 2021-10-21 05:52:47             🧑  作者: Mango

从网站中提取数据主要有两种方式:

  • 使用网站的 API(如果存在)。例如,Facebook 有 Facebook Graph API,它允许检索发布在 Facebook 上的数据。
  • 访问网页的 HTML 并从中提取有用的信息/数据。这种技术称为网络抓取或网络收集或网络数据提取。

本文讨论了使用名为 Beautiful Soup 的Python网页抓取框架的实现进行网页抓取所涉及的步骤。

网页抓取涉及的步骤:

  1. 向您要访问的网页的 URL 发送 HTTP 请求。服务器通过返回网页的 HTML 内容来响应请求。对于此任务,我们将使用第三方 HTTP 库来处理 Python 请求。
  2. 一旦我们访问了 HTML 内容,我们就剩下解析数据的任务了。由于大部分 HTML 数据是嵌套的,我们不能简单地通过字符串处理来提取数据。需要一个可以创建 HTML 数据的嵌套/树结构的解析器。有许多可用的 HTML 解析器库,但最先进的一个是 html5lib。
  3. 现在,我们需要做的就是导航和搜索我们创建的解析树,即树遍历。对于此任务,我们将使用另一个第三方Python库 Beautiful Soup。它是一个Python库,用于从 HTML 和 XML 文件中提取数据。

步骤 1:安装所需的第三方库

  • 在Python安装外部库的最简单方法是使用 pip。 pip是一个包管理系统,用于安装和管理用Python编写的软件包。
    您需要做的就是:
pip install requests
pip install html5lib
pip install bs4
  • 另一种方法是从这些链接手动下载它们:
    • 要求
    • html5lib
    • 美汤4

第 2 步:从网页访问 HTML 内容

import requests
URL = "https://www.geeksforgeeks.org/data-structures/"
r = requests.get(URL)
print(r.content)

让我们试着理解这段代码。

  • 首先导入请求库。
  • 然后,指定要抓取的网页的 URL。
  • 向指定的 URL 发送 HTTP 请求,并将来自服务器的响应保存在名为 r 的响应对象中。
  • 现在,打印 r.content 以获取网页的原始 HTML 内容。它是“字符串”类型。

第 3 步:解析 HTML 内容

#This will not run on online IDE
import requests
from bs4 import BeautifulSoup
  
URL = "http://www.values.com/inspirational-quotes"
r = requests.get(URL)
  
soup = BeautifulSoup(r.content, 'html5lib') # If this line causes an error, run 'pip install html5lib' or install html5lib
print(soup.prettify())

BeautifulSoup 库的一个真正好处是它建立在 HTML 解析库(如 html5lib、lxml、html.parser 等)之上。因此可以同时创建 BeautifulSoup 对象和指定解析器库。

在上面的例子中,

soup = BeautifulSoup(r.content, 'html5lib')

我们通过传递两个参数来创建一个 BeautifulSoup 对象:

  • r.content :它是原始 HTML 内容。
  • html5lib :指定我们要使用的 HTML 解析器。

现在打印soup.prettify() 它给出了从原始 HTML 内容创建的解析树的可视化表示。

第 4 步:搜索和导航解析树

现在,我们想从 HTML 内容中提取一些有用的数据。汤对象包含可以通过编程方式提取的嵌套结构中的所有数据。在我们的示例中,我们正在抓取一个包含一些引号的网页。因此,我们想创建一个程序来保存这些报价(以及有关它们的所有相关信息)。

#Python program to scrape website 
#and save quotes from website
import requests
from bs4 import BeautifulSoup
import csv
   
URL = "http://www.values.com/inspirational-quotes"
r = requests.get(URL)
   
soup = BeautifulSoup(r.content, 'html5lib')
   
quotes=[]  # a list to store quotes
   
table = soup.find('div', attrs = {'id':'all_quotes'}) 
   
for row in table.findAll('div',
                         attrs = {'class':'col-6 col-lg-3 text-center margin-30px-bottom sm-margin-30px-top'}):
    quote = {}
    quote['theme'] = row.h5.text
    quote['url'] = row.a['href']
    quote['img'] = row.img['src']
    quote['lines'] = row.img['alt'].split(" #")[0]
    quote['author'] = row.img['alt'].split(" #")[1]
    quotes.append(quote)
   
filename = 'inspirational_quotes.csv'
with open(filename, 'w', newline='') as f:
    w = csv.DictWriter(f,['theme','url','img','lines','author'])
    w.writeheader()
    for quote in quotes:
        w.writerow(quote)

在继续之前,我们建议您浏览我们使用soup.prettify() 方法打印的网页的HTML 内容,并尝试找到导航到引号的模式或方法。

  • 请注意,所有引号都在一个 id 为“all_quotes”的 div 容器内。因此,我们使用find()方法找到了 div 元素(在上面的代码中称为 table
    table = soup.find('div', attrs = {'id':'all_quotes'}) 

    第一个参数是您要搜索的 HTML 标签,第二个参数是一个字典类型元素,用于指定与该标签关联的附加属性。 find()方法返回第一个匹配元素。您可以尝试打印table.prettify()以了解这段代码的作用。

  • 现在,在 table 元素中,可以注意到每个引号都在一个类为 quote 的 div 容器中。因此,我们遍历每个类为引用的 div 容器。
    在这里,我们使用 findAll() 方法,它在参数方面类似于 find 方法,但它返回所有匹配元素的列表。现在每个引用都使用名为row的变量进行迭代
    这是一个示例行 HTML 内容,以便更好地理解:
    在 Python 中用 Beautiful Soup 实现网页抓取
    现在考虑这段代码:
    for row in table.find_all_next('div', attrs = {'class': 'col-6 col-lg-3 text-center margin-30px-bottom sm-margin-30px-top'}):
        quote = {}
        quote['theme'] = row.h5.text
        quote['url'] = row.a['href']
        quote['img'] = row.img['src']
        quote['lines'] = row.img['alt'].split(" #")[0]
        quote['author'] = row.img['alt'].split(" #")[1]
        quotes.append(quote)

    我们创建了一个字典来保存有关报价的所有信息。可以使用点表示法访问嵌套结构。要访问 HTML 元素内的文本,我们使用.text :

    quote['theme'] = row.h5.text

    我们可以添加、删除、修改和访问标签的属性。这是通过将标签视为字典来完成的:

    quote['url'] = row.a['href']

    最后,所有引号都附加到名为引号的列表中

  • 最后,我们想将所有数据保存在某个 CSV 文件中。
    filename = 'inspirational_quotes.csv'
    with open(filename, 'w', newline='') as f:
        w = csv.DictWriter(f,['theme','url','img','lines','author'])
        w.writeheader()
        for quote in quotes:
            w.writerow(quote)

    在这里,我们创建了一个名为 mindal_quotes.csv 的 CSV 文件,并将所有报价保存在其中以供进一步使用。

所以,这是一个如何在Python创建网络爬虫的简单示例。从这里,您可以尝试废弃您选择的任何其他网站。如有任何疑问,请在下面的评论部分发布。

注意:在许多情况下,网页抓取被认为是非法的。它还可能导致您的 IP 被网站永久封锁。