我正在参加中秋创意投稿大赛,详情请看:中秋创意投稿大赛。这是我的第一个爬虫程序,欢迎讨论交流。
前言
爬取唯品会月饼价格及详情数据使用的是python语言,如果你没有使用过python,请先安装python。初学爬虫时用的是requests第三方库,但是各大电商平台都有反爬机制,用requests时无法获取到页面数据。因此本文使用的是selenium。
第三方库
简介第三方库安装及在该程序中的用途
selenium
Selenium测试直接运行在浏览器中,就好像一个真正的用户在操作一样, 支持大部分主流的浏览器,包括IE(7,8,9,10,11),Firefox,Safari,Chrome,Opera等。 我们可以利用它来模拟用户点击访问网站,绕过一些复杂的认证场景 通过selenium+驱动浏览器这种组合可以直接渲染解析js,绕过大部分的参数构造和反爬。
1、安装:安装好python后pip即可使用。使用pip安装,执行命令:pip install selenium
2、下载chromedriver驱动:下载chromedriver.exe,下载地址点这里 注意:版本需要和你的浏览器版本相对应,下载完成后需要放在python目录下。
BeautifulSoup
BeautifulSoup主要是用来帮助我们结构化网页页面数据,方便我们检索需要的数据比如商品名称、价格、货号等。
使用pip安装,执行命令:pip install beautifulsoup4
实战爬取月饼相关数据
获取页面
打开唯品会官网并输入月饼,复制url如下:category.vip.com/suggest.php…
安装好python后打开cmd输入python,然后输入以下代码,是否执行并正确打开了浏览器
from selenium import webdriver
from bs4 import BeautifulSoup
url = "https://category.vip.com/suggest.php?keyword=%E6%9C%88%E9%A5%BC&ff=235|12|1|1" #vip地址
driver = webdriver.Chrome()
r = driver.get(url)
解析页面,获取商品数据
键盘f12打开调试工具,鼠标移入完整商品块观察网页数据,使用BeautifulSoup中的select方法获取到当前页面的所有月饼商品数据,并打印查看结果。
html = driver.page_source
bs = BeautifulSoup(html, "lxml")
course_data = bs.select('div[data-product-id]')
print(course_data)
解析商品详细数据
为了获取商品编码数据,需要点开打开详情页,因此for循环打开每个商品并使用BeautifulSoup获取数据,再构建对象将有用的信息塞入。
判断尺码那块逻辑可忽略,记录下来方便自己以后翻阅查看python写法。笔者是前端开发,写python机会较少。
for each_item in course_data:
detailUrl = each_item.find("a")
id = each_item.attrs['data-product-id']
goodsName = each_item.find("div", class_="c-goods-item__name") # 定位月饼名称
r1 = driver.get('https:'+detailUrl.attrs["href"]) #点开商品详情页
html1 = driver.page_source
bs1 = BeautifulSoup(html1, "lxml")
size_arr = [] #放置月饼规格数据
sizes = bs1.find_all("li", class_="size-list-item J-sizeID")
if sizes:
for each_item in sizes:
size = each_item.find('span', class_="size-list-item-name")
size_arr.append(size.getText())
elif bs1.find_all("li", class_="selector_opt"):
sizes = bs1.find_all("li", class_="selector_opt")
for each_item in sizes:
size = each_item.find('a').getText()
size_arr.append(size)
elif bs1.find_all("li", class_="size-list-item J-sizeID sli-selected size-list-item-small"):
sizes = bs1.find_all("li", class_="size-list-item J-sizeID sli-selected size-list-item-small")
for each_item in sizes:
size = each_item.find('span', class_="size-list-item-name")
size_arr.append(size.getText())
elif bs1.find_all("li", class_="size-list-item J-sizeID sli-selected"):
sizes = bs1.find_all("li", class_="size-list-item J-sizeID sli-selected")
for each_item in sizes:
size = each_item.find('span', class_="size-list-item-name")
size_arr.append(size.getText())
else:
size_arr = ['无货']
infoCode = bs1.find("p", class_="other-infoCoding").getText()
str=','.join(size_arr) #数组转字符串
goods_dict = {"goodsName": goodsName.getText(), "detailUrl": detailUrl.attrs["href"], "id": id, "infoCode": infoCode, "size": str}
list_data.append(goods_dict)
输出数据
通常我们会将爬取到的数据存入数据库,由于此处只是个demo,暂时先将月饼数据写入文本文件中。
print(list_data)
with open('mooncake_classes.txt', "a+") as f: # 将商品信息写入文本文件中
for text in list_data:
print(text)
f.write('商品名称:'+text['goodsName']+' 商品id:'+text['id']+' 货号:'+text['infoCode']+' 规格:'+text['size']+'\n')
总结
如果你已经跟着我的文章学习了一遍,可以试试获取价格数据,与获取名称数据同理。目前demo只是第一页的数据,可以点击底部按钮获取所有页数据,与点击详情同理。欢迎一起学习交流。