Pythonr基于selenium如何实现不同商城的商品价格差异分析系统

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

Pythonr基于selenium如何实现不同商城的商品价格差异分析系统
⽬录
1. 前⾔
2、程序设计流程
2.1 需求分析:
2.2 认识 selenium
2.3 功能函数设计
3. 总结
1. 前⾔
selenium 原本是⼀款⾃动化测试⼯具,因其出⾊的页⾯数据解析和⽤户⾏为模拟能⼒⽽常⽤于爬⾍程序中,致使爬⾍程序的爬取过程更简单、快捷。

爬⾍程序与其它类型程序相⽐较,本质⼀样,为数据提供处理逻辑,只是爬⾍程序的数据来源于 HTML 代码⽚段中。

怎样准确查找到页⾯中数据所在的标签(或叫节点、元素、组件)就成了爬⾍程序的关键,只有这⼀步成⽴,后续的数据提取、清洗、汇总才有可能。

相⽐较于 Beaufulsoup 模块, selenium 底层依靠的是强⼤的浏览器引擎,在页⾯解析能⼒上颇有王者的从容和决绝。

本⽂将使⽤ selenium ⾃动摸拟⽤户的搜索⾏为,获取不同商城上同类型商品的价格信息,最终⽣成商品在不同商城上的价格差对⽐表。

本⽂通过实现程序流程讲解 selenium,只会讲解程序中涉及到的 selenium 功能。

不会深究其它 selenium API 的细节。

所以你在阅读本⽂时,请确定你对 selenium 有所⼀点点的了解。

2、程序设计流程
2.1 需求分析:
本程序实现了⽤户不打开浏览器、只需要输⼊⼀个商品关键字,便能全⾃动化的实现在不同商城中查找商品价格,并汇总出价格⼀些差异信息。

1、程序运⾏时,提⽰使⽤者输⼊需要搜索的商品关键字。

本程序仅为探研 selenium 的奇妙之处,感受其王者风范,没有在程序结构和界⾯上费⼼⼒。

2、使⽤ selenium 摸拟⽤户打开京东和苏宁易购⾸页。

为什么选择京东和苏宁易,⽽不选择淘宝?
因为这 2 个⽹站使⽤搜索功能时没有登录验证需要,可简化本程序代码。

3、使⽤ selenium 在⾸页的⽂本搜索框中⾃动输⼊商品关键字,然后⾃动触发搜索按钮的点击事件,进⼊商品列表页⾯。

4、使⽤ selenium 分析、爬取不同商城中商品列表页⾯中的商品名称和价格数据。

5、对商品的价格数据做简单分析后,使⽤ CSV 模块以⽂件⽅式保存。

主要分析商品在不同商城上的平均价格、最低价格、最⾼体系的差异。

当然,如果有需要,可以借助其它的模块或分析逻辑,得到更多的数据分析结论。

2.2 认识 selenium
虽然本⽂不深究 selenium API 的细节,但是,既然要⽤它,其使⽤流程还是要⾯⾯俱到。

1、安装:
selenium 是 python 第三库,使⽤前要安装,安装细节就没必要在此多费笔墨。

pip3 install selenium
除了安装 selenium 模块,还需要为它下载⼀个浏览器驱动程序,否则它⽆法⼯作。

什么是浏览器驱动程序?为什么需要它?
解释这个问题,需要从 selenium 的⼯作原理说起。

2、浅淡 selenium 的⼯作原理:
Beautiful soup 使⽤特定的解析器程序解析 HTML 页⾯。

selenium 更⼲脆、直接借助浏览器的解析能⼒。

通过调⽤浏览器的底层 API 完成页⾯数据查找,也是跪服了,不仅爬取,还可以向浏览器模拟⽤户⾏为发送操作指令。

有没有感觉浏览器就是 selenium ⼿中的牵线⽊偶(玩弄浏览器于股掌之中)。

selenium 的⼯作就是驱动浏览器,向浏览器发送指令或接收浏览的反馈,此过程中,浏览器驱动程序(webdriver)就起到了上传下达的作⽤。

典型的组件开发模式。

很显然,因不同浏览器的内核存在差异性,驱动程序必然也不相同,所以,下载驱动程序之前,请确定你使⽤的浏览器类型和版本。

本⽂使⽤⾕歌浏览器,需要下载与⾕歌浏览器对应的 webdriver 驱动程序。

请选择与正使⽤的浏览版本⼀致的驱动程序。

下载完毕后,指定⼀个驱动程序的存放⽬录,本⽂存放在 D:\chromedriver\chromedriver.exe 。

也可存放在浏览器的安装⽬录。

2.3 功能函数设计
准备⼯作就绪后,开始编码:
导⼊程序所需要的模块,定义程序所需要的变量。

from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from mon.by import By
import csv
import time
import math
# 浏览器对象
chrome_browser = None
# 商品关键字
search_keyword = None
# 保存在京东商城搜索到的商品数据,格式{商品名:价格}
jd_data = {}
# 保存在苏宁商城搜索到的商品数据,格式{商品名:价格}
sn_data = {}
webdriver:⽤来构建浏览器对象,从底层设计⾓度讲,是 selenium 和浏览器之间的接⼝层。

selenium 向上为⽤户提供⾼级应⽤接⼝,向下通过 webdriver 和浏览器⽆障碍沟通。

Service: webdriver 构建浏览器对象时的参数类型。

By: ** 封装了查找页⾯组件的各种⽅式。

selenium** 向开者提供了很多⾼级⽅法⽤来查询 HTML 页⾯组件,如通过元素 ID、样式、样式选择器、XPATH……By 封装了这些⽅案。

诸如:find_element_by_class_name( )、 find_element_by_id()、find_element_by_()、find_element_by_tag_name()、find_element_by_class_name()、find_element_by_xpath()、find_element_by_css_selector()
以上⽅法已经被标注为过时,请使⽤ find_element( ) ⽅法,配合 By 对象切换⽅式。

csv:⽤来把获取到的数据以 csv 格式保存。

time:时间模块,⽤来模拟⽹络延迟。

math:数学模块,辅助数据分析。

初始化函数:初始化浏览器对象和⽤户输⼊数据
'''
初始浏览器对象
'''
def init_data():
# 驱动程序存放路径
webdriver_path = r"D:\chromedriver\chromedriver.exe"
service = Service(webdriver_path)
# 构建浏览器对象
browser = webdriver.Chrome(service=service)
# 等待浏览器就绪
browser.implicitly_wait(10)
return browser
'''
初始⽤户输⼊的商品名称关键字
'''
def input_search_key():
info = input("请输⼊商品关键字:")
return info
查询京东商品信息。

在京东商城查询商品,分两个步骤,在⾸页输⼊商品关键字,点击搜索后,在结果页⾯查询价格信息。

完整代码如下:
'''
进⼊京东商城查询商品信息
'''
def search_jd():
global jd_data
products_names = []
products_prices = []
# 京东⾸页
jd_index_url = r"https:///"
# 打开京东⾸⾯
try:
if chrome_browser is None:
raise Exception()
else:
# 打开京东⾸页
chrome_browser.get(jd_index_url)
# 模拟⽹络延迟
chrome_browser.implicitly_wait(10)
# 找到⽂本输⼊组件
search_input = chrome_browser.find_element(By.ID, "key")
# 在⽂本框中输⼊商品关键字
search_input.send_keys(search_keyword)
chrome_browser.implicitly_wait(5)
# 找到搜索按钮这⾥使⽤ CSS 选择器⽅案
search_button = chrome_browser.find_element(By.CSS_SELECTOR, "#search > div > div.form > button")
# 触发按钮事件
search_button.click()
chrome_browser.implicitly_wait(5)
# 获取所有打开的窗⼝(当点击按钮后应该有 2 个)
windows = chrome_browser.window_handles
# 切换新打开的窗⼝,使⽤负索引找到最后打开的窗⼝
chrome_browser.switch_to.window(windows[-1])
chrome_browser.implicitly_wait(5)
# 获取商品价格
product_price_divs = chrome_browser.find_elements(By.CLASS_NAME, "p-price")
for i in range(5):
div = product_price_divs[i]
if len(div.text) != 0:
# 删除价格前⾯的美元符号
products_prices.append(float(div.text[1:]))
# 获取商品名称
product_name_divs = chrome_browser.find_elements(By.CLASS_NAME, "p-name")
chrome_browser.implicitly_wait(10)
for i in range(5):
div = product_name_divs[i]
if len(div.text) != 0:
products_names.append(div.text)
jd_data = dict(zip(products_names, products_prices))
jd_data["平均价格"] = sum(products_prices) / len(products_prices)
jd_data["最低价格"] = min(products_prices)
jd_data["最⾼价格"] = max(products_prices)
# 使⽤ CSV 模块写⼊⽂档
csv_save("京东商城", jd_data)
except Exception as e:
print(e)
chrome_browser:由 webdriver 构建出来的对浏览器映射的对象,selenium 通过此对象控制对浏览器的所有操作。

此对象有⼀个 find_element( ) 核⼼⽅法,⽤来查找(定位)HTML 页⾯元素。

查找时,可以通过 By 对象指定查找的⽅式(这⾥使⽤了⼯⼚设计模式), By 的取值可以是 ID、CSS_SELECTOR、XPATH、CLASS_NAME、CSS_SELECTOR、TAG_NAME、LINK_TEX、PARTIAL_LINK_TEXT。

打开京东⾸页后,先定位定位⽂本搜索框和搜索按钮。

使⽤浏览器的开发者⼯具,检查到⽂本框的源代码是⼀段 input html ⽚段,为了精确地定位到此组件,⼀般先试着分析此组件有没有独有的属性或特征值,id 是⼀个不错的选择。

html 语法规范 id 值应该是⼀个唯⼀值。

search_input = chrome_browser.find_element(By.ID, "key")
找到组件后,可以对此组件进⾏⼀系列操作,常⽤的操作:
text 属性:获取组件的⽂本内容。

send_keys( ) ⽅法:为此组件赋值。

get_attribute( ) ⽅法:获取组件的属性值。

这⾥使⽤ send_keys 给⽂本组件赋予⽤户输⼊商品关键字。

search_input.send_keys(search_keyword)
再查找搜索按钮组件:
按钮组件是⼀段 button html 代码,没有过于显著的特性属性值,为了找到这个唯⼀组件,可以使⽤ XPATH 或 CSS 选择器⽅式。

右击此代码⽚段,在弹出的快捷菜单中找到“复制”命令,再找到此组件的 CSS选择器值。

search_button = chrome_browser.find_element(By.CSS_SELECTOR, "#search > div > div.form > button")
调⽤按钮组件的 click() ⽅法,模拟⽤户点击操作,此操作会打开新窗⼝,并以列表⽅式显⽰搜索出来的商品数据。

search_button.click()
selenium 接收到浏览器打开新窗后的反馈后,可以使⽤ window_handles 属性获取浏览器中已经打开的所有窗⼝,并以列表的⽅式存储每⼀个窗⼝的操作引⽤。

windows = chrome_browser.window_handles
对页⾯元素进⾏定位查找时,有⼀个当前窗⼝(当前可以、正在操作的窗⼝)的概念。

刚开始是在⾸页窗⼝操作,现在要在搜索结果窗⼝中进⾏操作,所以要切换到刚打开的新窗⼝。

使⽤负索引得到刚打开的窗⼝(刚打开的窗⼝⼀定是最后⼀个窗⼝)。

chrome_browser.switch_to.window(windows[-1])
注意,这时切换到了搜索结果窗⼝,便可以在这个窗⼝中搜索所需要组件。

在这个页⾯中,只需要获取前 5 名的商品具体信息,包括商品名、商品价格。

⾄于具体要获取什么数据,可以根据⾃⼰的需要定夺。

本程序只需要商品的价格和名称,则检查页⾯,找到对应的 html ⽚段。

商品名信息存放在⼀个 div ⽚段中,此 div 有⼀个值为 p-name 的 class 属性。

可以使⽤ CSS-NAME ⽅式获取,因为所有的商品采⽤相同⽚段模板,这⾥使⽤ find_elements( ) ⽅法即可。

product_name_divs = chrome_browser.find_elements(By.CLASS_NAME, "p-name")
find_elements ⽅法返回具有相同 CSS-NAME 的组件列表,编写代码迭代出每⼀个组件,并获取数据,然后存储在商品名称列表中。

for i in range(5):
div = product_name_divs[i]
if len(div.text) != 0:
products_names.append(div.text)
以同样的⽅式,获取到价格数据。

再把商品名称和价格数据制成字典,并对价格数据做简单分析。

jd_data = dict(zip(products_names, products_prices))
jd_data["平均价格"] = sum(products_prices) / len(products_prices)
jd_data["最低价格"] = min(products_prices)
jd_data["最⾼价格"] = max(products_prices)
csv_save("京东商城", jd_data)
以 CSV 格式存储从京东商城上爬取下来的数据。

获取苏宁易购上的商品数据。

与从京东上获取数据的逻辑⼀样(两段代码可以整合到⼀个函数中,为了便于理解,本⽂分开编写)。

两者的区别在于页⾯结构、承载数据的页⾯组件不⼀样或组件的属性设置不⼀样。

def search_sn():
global sn_data
# 保存商品名称
products_names = []
# 保存商品价格
products_prices = []
# 苏宁⾸页
sn_index_url = r"https:///"
try:
if chrome_browser is None:
raise Exception()
else:
# 打开⾸页
chrome_browser.get(sn_index_url)
# 摸拟⽹络延迟
chrome_browser.implicitly_wait(10)
# 查找⽂本输⼊组件
search_input = chrome_browser.find_element(By.ID, "searchKeywords")
# 在⽂本框中输⼊商品关键字
search_input.send_keys(search_keyword)
time.sleep(2)
# 找到搜索按钮这⾥使⽤ CSS 选择器⽅案
search_button = chrome_browser.find_element(By.ID, "searchSubmit")
# 触发按钮事件
search_button.click()
time.sleep(3)
# 获取所有打开的窗⼝(当点击按钮后应该有 2 个)
windows = chrome_browser.window_handles
# 切换新打开的窗⼝,使⽤负索引找到最后打开的窗⼝
chrome_browser.switch_to.window(windows[-1])
chrome_browser.implicitly_wait(20)
# 获取商品价格所在标签
product_price_divs = chrome_browser.find_elements(By.CLASS_NAME, "def-price")
# 仅查看前 5 个商品信息
for i in range(5):
div = product_price_divs[i]
# 删除价格前⾯的美元符号
if len(div.text) != 0:
products_prices.append(float(div.text[1:]))
chrome_browser.implicitly_wait(10)
# 获取商品名称
product_name_divs = chrome_browser.find_elements(By.CLASS_NAME, "title-selling-point")
for i in range(5):
products_names.append(product_name_divs[i].text)
#
sn_data = dict(zip(products_names, products_prices))
sn_data["平均价格"] = sum(products_prices) / len(products_prices)
sn_data["最低价格"] = min(products_prices)
sn_data["最⾼价格"] = max(products_prices)
# 使⽤ CSV 模块写⼊⽂档
csv_save("苏宁商城", sn_data)
except Exception as e:
print(e)
获取到苏宁易购上的商品数据后,同样以 CSV 格式存储。

存储最终的分析结果。

这⾥仅分析了两个商城上同类型商品的平均价格、最低价、最⾼价的差异性。

def price_result():
if len(jd_data) != 0 and len(sn_data) != 0:
with open("d:/商品⽐较表.csv", "w", newline='') as f:
csv_writer = csv.writer(f)
jd_name = list(jd_data.keys())
jd_price = list(jd_data.values())
sn_price = list(sn_data.values())
csv_writer.writerow(["⽐较项", "京东价格", "苏宁价格", "价格差"])
for i in range(5, len(jd_price)):
csv_writer.writerow([jd_name[i], jd_price[i], sn_price[i], math.fabs(jd_price[i] - sn_price[i])])
保存了两个商城上商品价格的平均值、最⼩值、最⼤值以及绝对差。

最终测试代码
if __name__ == '__main__':
search_keyword = input_search_key()
chrome_browser = init_data()
search_jd()
time.sleep(2)
search_sn()
price_result()
请输⼊商品关键字:华为meta 40
3. 总结
本⽂主要是应⽤ selenium 。

通过应⽤过程对 selenium 做⼀个讲解,了解 selenium 的基本使⽤流程。

数据分析并不是本⽂的重点。

如果要得到更全⾯的分析结果,则需要提供更多维度的数据分析逻辑。

到此这篇关于Pythonr基于selenium如何实现不同商城的商品价格差异分析系统的⽂章就介绍到这了,更多相关Pythonr selenium商品价格差异分析系统内容请搜索以前的⽂章或继续浏览下⾯的相关⽂章希望⼤家以后多多⽀持!。

相关文档
最新文档