Python爬虫包 BeautifulSoup 递归抓取实例详解
什么是BeautifulSoup?
BeautifulSoup 是 Python 的一个 HTML 解析库,它可以自动解析 HTML 文档,并提供了许多简便的方法来处理 HTML 元素。它可以轻松地帮助我们快速提取出需要的信息,是一个强大的工具。
安装BeautifulSoup
使用pip可以很方便地安装beautifulsoup4
pip install beautifulsoup4
递归抓取实例
在这里,我们将使用递归函数来抓取并解析HTML文档。递归这个函数可以帮助我们遍历整个HTML文档,将需要的信息从HTML中提取出来。
为了演示这个例子,我们将从网站上爬取手机分类数据。首先,我们需要确定要抓取的网页。我们可以使用Python中的requests和BeautifulSoup包。
import requests
from bs4 import BeautifulSoup
url = 'http://www.example.com/mobile'
response = requests.get(url)
soup = BeautifulSoup(response.text, 'html.parser')
接下来,我们需要找到HTML中包含手机信息的元素。为此,我们需要使用Chrome或Firefox这样的浏览器,并使用它们提供的开发者工具检查HTML文档中的元素。
在此示例中,我们将从以下HTML文档开始:
<html>
<body>
<div class="products">
<div class="product">
<h2>iPhone X</h2>
<p>Price: $999</p>
</div>
<div class="product">
<h2>Samsung Galaxy S9</h2>
<p>Price: $840</p>
</div>
<div class="product">
<h2>LG G7 ThinQ</h2>
<p>Price: $749</p>
</div>
</div>
</body>
</html>
我们要提取的信息是每个产品的名称和价格。这些信息包含在class为product
的div
元素中,每个产品的名称和价格分别包含在h2和p元素中。
接下来,我们将包含所有产品信息的div元素传递给递归函数,并使用递归函数提取名称和价格信息。
def get_products_info(products):
for product in products:
name = product.find('h2').text
price = product.find('p').text
print(name, price)
# 对每个产品调用递归函数,以便处理其子元素
children = product.findChildren("div" , recursive=False)
get_products_info(children)
# 获取所有 class为“products”的div元素和其所有子元素
products_div = soup.find('div', {'class': 'products'})
get_products_info([products_div])
这个递归函数执行以下步骤:
- 获取传递的产品div元素的名称和价格。
- 通过处理传递的产品div元素的子元素,递归调用自己。
当递归函数被调用时,它将处理传递的div元素的所有子元素,并获取它们的名称和价格。如果我们的HTML文档中有任何嵌套的产品元素,该函数将仅处理当前div元素的子元素,并递归调用自己以处理这些子元素。
示例说明
示例1:递归处理nested div
让我们通过以下HTML文档来展示这个递归过程:
<html>
<body>
<div class="products">
<div class="product">
<h2>iPhone X</h2>
<p>Price: $999</p>
<div class="features">
<p>Screen Size: 5.8 inches</p>
<p>RAM: 3 GB</p>
</div>
</div>
<div class="product">
<h2>Samsung Galaxy S9</h2>
<p>Price: $840</p>
<div class="features">
<p>Screen Size: 5.8 inches</p>
<p>RAM: 4 GB</p>
</div>
</div>
</div>
</body>
</html>
代码如下:
def get_products_info(products):
for product in products:
name = product.find('h2').text
price = product.find('p').text
print(name, price)
# 对每个产品调用递归函数,以便处理其子元素
children = product.findChildren("div" , recursive=False)
get_products_info(children)
# 获取所有 class为“products”的div元素和其所有子元素
products_div = soup.find('div', {'class': 'products'})
get_products_info([products_div])
输出结果如下:
iPhone X Price: $999
Screen Size: 5.8 inches
RAM: 3 GB
Samsung Galaxy S9 Price: $840
Screen Size: 5.8 inches
RAM: 4 GB
这个递归过程处理了外部div中的两个产品元素,以及每个产品元素内部的特征div元素。由于函数在处理每个div元素时都会递归调用自己,因此我们可以处理多个嵌套电子元素。
示例2:处理包含孩子的字典
假设我们想要从下面的HTML文档中提取每个电子产品的名称和价格,但我们希望将其作为字典输出:
<html>
<body>
<div class="products">
<div class="product" data-id="1">
<h2>iPhone X</h2>
<p>Price: $999</p>
</div>
<div class="product" data-id="2">
<h2>Samsung Galaxy S9</h2>
<p>Price: $840</p>
</div>
<div class="product" data-id="3">
<h2>LG G7 ThinQ</h2>
<p>Price: $749</p>
</div>
</div>
</body>
</html>
我们可以使用以下代码:
def get_products_info(products):
all_products = {}
for product in products:
product_dict = {}
name = product.find('h2').text
price = product.find('p').text
product_dict['name'] = name
product_dict['price'] = price
# 对每个产品调用递归函数,以便处理其子元素
children = product.findChildren("div" , recursive=False)
if children:
product_dict['children'] = get_products_info(children)
# 将产品字典添加到所有产品字典中
data_id = product['data-id'] # 使用data-id属性作为键
all_products[data_id] = product_dict
return all_products
# 获取所有class为“products”的div元素和其所有子元素
products_div = soup.find('div', {'class': 'products'})
all_products = get_products_info([products_div])
print(all_products)
输出结果如下:
{
'1': {
'name': 'iPhone X',
'price': 'Price: $999'
},
'2': {
'name': 'Samsung Galaxy S9',
'price': 'Price: $840'
},
'3': {
'name': 'LG G7 ThinQ',
'price': 'Price: $749'
}
}
在这个例子中,我们使用所有产品字典记录每个产品的名称和价格,并将其包含的所有子元素存储在名为children
的键下。我们还将data-id属性用作每个产品字典的键,可以根据键轻松地找到每个产品的字典。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Python爬虫包 BeautifulSoup 递归抓取实例详解 - Python技术站