学习Python自动化的一个好办法就是构建一个价格追踪器。由于这项任务生成的脚本可以立即投入使用,所以对于初学者来说尤为方便。
本文将向大家介绍如何用Python采集器建立一个可立即实现电商价格跟踪的可扩展价格追踪器。
价格追踪器是什么?
价格追踪器是一个定期在电商网站上抓取产品价格并提取价格变动的程序。
除了网络抓取这一基本功能外,价格追踪器还配备其他功能,例如当产品价格低于某一阈值时,它就会发出电子邮件提醒。
一个简单的Python脚本可用于处理个人任务,而更复杂的价格追踪器则用于追踪数百万种产品的价格。
价格追踪的目的
价格追踪的好处多多。对于您个人来说,通过价格追踪您可能会以最低价买到一个心仪的产品。
对于公司来说,价格追踪器可以检测竞争对手的销售价格,观察对方何时会对相同的产品展开优惠活动,或为您的产品定一个能实现最佳利润率的价格。价格追踪软件可以帮助您恰到好处地调整价格。
搭建Python价格追踪脚本
本节将展示一个用于追踪多种产品价格的Python脚本。我们将使用网络抓取技术来提取产品数据,并自动通过Python发送邮件来提醒用户注意价格变动。
项目要求
以下Python价格追踪脚本适用于Python 3.6及以上版本。推荐的库如下所示:
●Requests:用于发送HTTP请求。换句话说,就是在没有浏览器的情况下下载网页。Requests是后续价格追踪脚本的基础库。
●BeautifulSoup:用于查询HTML中的特定元素,封装解析器库。
●lxml:用于解析HTML文件。Requests库检索出来的HTML是一个字符串,在查询前需要解析成一个Python对象。我们不会直接使用这个库,而是使用BeautifulSoup来进行封装以获得更直接的API。
●价格解析器:用于每个价格监测脚本的库。它有助于从包含价格的字符串中提取价格。
●smtplib:用于发送电子邮件。
●Pandas:用于过滤产品数据和读写CSV文件。
此外,您也可以创建一个虚拟环境让整个过程更加有序。
代码语言:javascript复制$ python3 -m venv .venv
代码语言:javascript复制$ source .venv/bin/activate
打开终端并运行以下命令,安装依赖项:
代码语言:javascript复制$ pip install pandas requests beautifulsoup4 price-parser
请注意,smtlib库属于Python标准库,无需单独安装。
安装完成后,创建一个新的Python文件并导入以下代码:
代码语言:javascript复制import smtplib
import pandas as pd
import requests
from bs4 import BeautifulSoup
from price_parser import Price
此外,添加以下代码用于初始配置:
代码语言:javascript复制PRODUCT_URL_CSV="products.csv"
SAVE_TO_CSV = True
PRICES_CSV = “prices.csv"
SEND_MAIL = True
包含目标URL的CSV为
代码语言:javascript复制PRODUCT_URL_CSV
如果SAVE_TO_CSV标志被设置为True,那么获取的价格将存储在PRICES_CSV指定的CSV文件中。
SEND_MAIL是一个标志,可以设置为True来发送电子邮件提醒。
读取产品的 URL 列表
存储和管理产品URL最简单的办法就是将它们保存在CSV或JSON文件中。这次使用的是CSV,便于我们通过文本编辑器或电子表格应用程序进行更新。
CSV文件应该至少包含两个字段——url和alert_price。产品的标题可以从产品的URL中提取,也可以存储在同一个CSV文件中。如果价格追踪器发现产品价格降至低于alert_price字段的值,它将触发一个电子邮件提醒。
CSV中的产品URL样本
可以使用Pandas读取CSV文件并转换为字典对象。接着我们会用一个简单的函数来封装。
代码语言:javascript复制def get_urls(csv_file):
df = pd.read_csv(csv_file)
return df
该函数将返回一个Pandas的DataFrame对象,其中包含三栏:产品、URL和alert_price(参考上图)。
抓取价格
第一步就是在目标URL上进行循环。
请注意,get_urls()返回一个DataFrame对象。
首先使用Pandas的to_dict()方法运行一个循环。
当to_dict方法在参数为records的情况下被调用时,它会将DataFrame转换为一个字典列表。
在每个字典上运行一个循环,如下所示:
代码语言:javascript复制def process_products(df):
for product in df.to_dict("records"):
# product["url"] is the URL
我们将在写完另外两个函数后重新审视这个方法。第一个函数是为了获得HTML,第二个函数则用于从中提取价格。
运行以下函数,从每个URL的响应中获得HTML:
代码语言:javascript复制def get_response(url):
response = requests.get(url)
return response.text
接下来,根据响应创建一个BeautifulSoup对象,使用CSS选择器定位价格元素。使用价格解析器库提取价格浮点,以便与提醒价格进行比较。如果您想深入了解价格解析器库的运行原理,请前往我们的GitHub资源库查看示例。
以下函数将从给定的HTML中提取价格,并将其作为一个价格浮点返回:
代码语言:javascript复制def get_price(html):
soup = BeautifulSoup(html, "lxml")
el = soup.select_one(".price_color")
price = Price.fromstring(el.text)
return price.amount_float
请注意,本例中使用的CSS选择器专门用于抓取目标。如果您正在处理其他网站,这是您唯一要改代码的地方。
在CSS选择器的帮助下,我们使用BeautifulSoup来定位一个包含价格的元素。该元素存储在el变量中。el标签的文本属性el.text包含价格和货币符号。价格解析器会解析这个字符串,然后提取价格的浮点值。
DataFrame的对象中有一个以上的产品URL。我们来循环运行所有代码,用新的信息更DataFrame。
最简单的方法是将每一行转换成一个字典。这样,您可以读取URL,调用get_price()函数,并更新所需字段。
我们将添加两个新的键值——提取的价格(price)和一个布尔值(alert),用于在发送邮件时过滤函数行。
现在可以扩展process_products()函数来演示上述序列:
代码语言:javascript复制def process_products(df):
updated_products = []
for product in df.to_dict("records"):
html = get_response(product["url"])
product["price"] = get_price(html)
product["alert"] = product["price"] < product["alert_price"]
updated_products.append(product)
return pd.DataFrame(updated_products)
这个函数将返回一个新的DataFrame对象,包含产品的URL和从CSV中读取的名称。此外,它还包括用于在价格下降时发送电子邮件的价格和提醒标志。
如果您对使用Python构建价格追踪器有兴趣,您可查看这里了解更多详情!