使用 Python 进行网页抓取简介:从页面中提取数据

在此系列文章/教程,我想向您介绍网络抓取的世界。到最后,我的目标是让您掌握技能和知识,能够访问网络上的大多数网站并提取其数据以供自己研究之用。

网络抓取非常有趣,它带来的可能性不容小觑。研究是内容营销的未来,因此,拥有进行自己的研究和分析的能力肯定会开阔你的视野和机会。

不过,本系列教程并非没有先决条件。在开始学习之前,您应该了解Python 的基础知识。如果您不知道从哪里开始,我强烈建议您遵循 Dataquest.io 提供的免费初学者课程。它是免费的,对我来说很有用,它将为您提供进一步学习所需的基本知识。

如果你已经了解一点 Python,但不确定这是否足够,你只需要知道如何创建列表、字典和循环。了解函数肯定是加分项。此外,对HTML 工作原理有基本的了解也是一个加分项,但不是强制性的。

我建议你跟着我一起打开 Jupyter Notebook,复制我们一起前进的步骤。我相信只有边做边学。如果你还没有准备好 Python 环境,你可以阅读我的文章解释 如何在浏览器中使用 Python 编写代码。Google合作实验室是提到的工具之一,因此您应该能够在浏览器中按照我的提示进行操作:)。

如果你不想在这个页面上停留太久,我还将本教程编译成了 Jupyter Notebook,你可以通过这个Google合作实验室关联。

别再说了。准备好了吗?开始吧。

导入必要的库
库相当于 Google Sheets 的附加组件,但适用于 Python。库可为您的 Python 代码添加功能。几乎所有东西都有库。今天,我们想学习如何使用用于网页抓取的库之一,即 BeautifulSoup。

对于网页抓取,你将需要以下库:

请求(http://docs.python-requests.org/en/master/user/quickstart/#make-a-request)
BeautifulSoup ( https://www.crummy.com/software/BeautifulSoup/bs4/doc/ )

每个图书馆都有自己的特色和特点他们的拥有自己的变量和函数。了解 Python 就是知道如何创建列表、字典以及如何学习库。当你不记得如何使用库时,不要犹豫,用 Google 搜索。这类流行库的文档非常详细,涵盖了你能想到的所有可能的用例。

下面的代码展示了如何将库导入到当前环境中。换句话说,导入库就是教你的 Python代码如何说一门新语言。因此,通过导入 BeautifulSoup 和 Requests,我们现在教会了 Python 代码如何抓取网站。

import requests
from bs4 import BeautifulSoup

如果您的环境没有安装 BeautifulSoup,请打开您的终端,输入此内容并再次运行您的代码:

pip install beautifulsoup4

获取页面内容
现在您的 Python 代码知道如何进行网络抓取,我们要做好准备。抓取工具面临的一个常见问题是网站会将它们识别为机器人。为了解决这个问题,我们使用“标头”。“标头”是机器人伪装自己并看起来像真实计算机的一种方式。

下面的代码显示了如何创建标题。

headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36'}

我们要输入的第二件事是我们要从中提取数据的 URL。出于本教程的目的,我们将研究从 Apple 网站提取 MacBook Pro 的价格。

url = "https://www.apple.com/shop/buy-mac/macbook"

从页面提取数据
现在我们有了 URL,并且 Python 使用正确的语言,是时候调用库并获取该网页的代码了。

为了实现这一目标,我们要做的第一件事就是发出请求。这意味着调用我们提供的 URL 来查看它是否存在。
然后我们要从中提取内容
最后,我们想把所有这些内容都交给 BeautifulSoup,这个库将使我们能够查看页面内容并对其进行处理

# First we "get" the URL using requests

request = requests.get(url, headers=headers)

# Then we retrieve the content

content = request.content

# Finally, we give this content to BeautifulSoup

soup = BeautifulSoup(content, 'lxml')

print(soup)

变量“soup”现在包含网页的所有代码。如果您熟悉 HTML/CSS,那么 soup 基本上就是页面的源代码。

现在我们有了内容。我们基本上可以与其交互并寻找特定的东西。

HTML 中内容的工作方式是所有内容都包含在“

Content

”之类的标签中。这些标签之间的所有内容都可以提取。

通常,此类标签还包含 class 或 ids。

为了查找内容,我们需要检查我们要提取数据的网页。

右键单击要提取的页面元素
点击“检查”
检查工具
这将在您的窗口中显示一个面板,其中包含您检查的元素的代码。在本例中,我们要提取计算机的“标题”。代码如下所示:

现在,我们知道我们要提取“h3”标签内的文本,并且该标签有一个名为“as-macbundle-modelvariationtitle”的类

查找元素的代码如下:

find_tag = soup.find(attrs={"class" : "as-macbundle-modelvariationtitle"})

print(find_tag)

# >>> <h3 class="as-macbundle-modelvariationtitle">1.2GHz Processor<br/> 256GB Storage</h3>

# This code finds the first HTML tag that has a class named "as-macbundle-modelvariationtitle"

find_text = find_tag.text

print(find_text)

# >>> 1.2GHz Processor 256GB Storage

# Printing "find_tag" shows us the whole tag and its content. You can get the text content of the tag by adding ".text" after your result.

需要找到一种方法来在要点中显示结果吗?

您可以注意到,变量“find_text”现在包含我们正在检查的精确文本。

使用同样的方法,我们现在可以查找这台笔记本电脑的价格。

通过右键点击网页上的价格检查,我们发现笔记本电脑的价格就在这个标签的内容中

<span class="as-price-currentprice" data-autom="price-MNYF2">
        <span>
            $1,299.00
        </span>
</span>

有两种方法可以找到这个具体的价格:

# First way is to follow the same exact way of doing than before :

price_tag = soup.find(attrs={"class" : "as-price-currentprice"})

price_text = price_tag.text

print(price_text)


# The second way is to not look for the class of the tag but for its other attribute :

price_tag_2 = soup.find(attrs={"data-autom" : "price-MNYF2"})

price_text_2 = price_tag_2.text

print(price_text_2)


# This second way of doing is more encouraged. As you may have noticed, "data-autom" and its value "price-MNYF2" is pretty unique.

# If an other tag in the page would have the class "as-price-currentprice" earlier, our scraper would have found the incorrect one first.


# Finally, you can see that the text result is full of white and useless space. The strip() function will get rid of all of this useless crap.

price_text_clean = price_text.strip()

print(price_text_clean)

# >>> $1,299.00

另外,所有这些代码实际上不必包含在这么多行中。你可以像这样在一行中获取相同的内容:

price = soup.find(attrs={"class" : "as-price-currentprice"}).text.strip()

print(price)

# >>> $1,299.00
# So there you have it, the product name and its price :

product_name = soup.find(attrs={"class" : "as-macbundle-modelvariationtitle"}).text.strip()

product_price = soup.find(attrs={"class" : "as-price-currentprice"}).text.strip()


print(f"The product '{product_name}' is sold at '{product_price}'")

# >>> The product '1.2GHz Processor 256GB Storage' is sold at '$1,299.00'

概括
这就是关于如何从网页获取数据的介绍。

在下一篇文章中,我们将学习如何将其与循环结合使用以浏览大量数据并自动检索。

目标是从数位城市页面…如果你有兴趣建立一个关于各城市生活成本的数据集,这正是我们要做的……