作业要求:解析本地网页信息,收集商品信息
爬虫作业1_2.png我的代码
# -*- coding:utf-8 -*-
#这次作业完成从商品网页上爬取商品信息,并保存到一个列表中
#一个商品信息包括:
# {图片地址:pic, 价格: price, 商品标题: title, 评分量: review, 评分星级: star}
from bs4 import BeautifulSoup
with open("/Users/xyh/Documents/python/python3/Week1/1_2/index.html") as webSite:
soup = BeautifulSoup(webSite, 'lxml')
pics = soup.select('body > div > div > div.col-md-9 > div > div > div > img')
prices = soup.select('body > div > div > div.col-md-9 > div > div > div > div > h4.pull-right')
titles = soup.select('body > div > div > div.col-md-9 > div > div > div > div > h4 > a')
reviews = soup.select('div > div.ratings > p.pull-right')
stars = soup.select('div > div.ratings > p:nth-of-type(2)')
products = []
for pic, price, title, review, star in zip(pics, prices, titles, reviews, stars):
data = {
'pic' : pic.get('src'),
'price' : price.get_text(),
'title' : title.get_text(),
'review' : int(review.get_text().split(' ')[0]), #只需要reviews的数量,并且以integer格式保存
'star' : '★' * len(star.find_all('span', class_='glyphicon glyphicon-star')) +
'☆' * len(star.find_all('span', class_='glyphicon glyphicon-star-empty'))
}
products.append(data)
print(products)
总结
- 遇到的坑 关于CSS selector
- 格式必须要对
-
正确:
div > div.ratings > p.pull-right
(div
空格>
空格div
) -
错误:
'div> div.ratings > p.pull-right
(少了空格,会报错)
-
正确:
- 直接从Google Chrome中复制selector路径,如果得到了
p:nth-child(2)
的路径,需要把nth-child(2)
改为nth-of-type(2)
,否则会报错
-
关于字段的存储类型:
-
星星数量最好以float或者integer数据类型保存, 由于作业没有给出明确的要求,因此,星星是以字符串''★''的形式打印出来。如果是要以星星数量筛选商品。
-
reviews的数量,作业中也做了处理,将"reviews"的字符串剔除,只保存前面的数字,用integer类型存储,便于之后的利用
-
-
星星数量的爬取
这个应该是本次作业中的难点,思路如下。-
定位星星位置:星星在一个
<p>
标签下的<span>
标签内,并且一个商品有多个星星。因此用soup.select()定位<span>
标签的父标签 -
分析
<span>
的类型: 一个商品有多个<span>
,分为两类:class_='glyphicon glyphicon-star'
代表''★'';class_='glyphicon glyphicon-star-empty
代表'☆' - 利用步骤1得到的列表中的每一个tag对象的find_all()方法,分别获取步骤2中分析出的两种
<span>
,分别得到两个list,用len()
函数就可以计算出每一个商品的两种类型的星星数量
-
定位星星位置:星星在一个
网友评论