不知道给女朋友买什么 ?让爬虫告诉你 !

2019-11-12 17:24:50 浏览数 (1)

本文来源: 公众号从零开始学爬虫

引言

你是否曾经遇到过要给女朋友、父母、好朋友送礼物却不知道买什么的情况?小编作为一个直男,每次都在给朋友选礼物的事情上费劲脑筋,实在是不知道买什么东西好。但事情总是要解决,小编萌生了一个想法,在某购物网站搜索关键字,然后将搜索结果进行词频分析,这样不就知道有什么东西是大家买的比较多的了么?说干咱就干。

需求分析

通过京东购物网站搜索关键字,将搜索结果中的产品名称进行保存,同时对产品名称进行词频统计,生成可供参考的词云图。

所用知识点

爬虫:requests库(简单的项目,使用requests更方便)

分词:jieba库

词云:pyecharts库

保存文件:csv库

页面解析:BeautifulSoup

目标网站分析

打开京东网站,输入关键字,本例中使用“情人节”,点击搜索。可以看到搜索结果页面如下图所示。除去广告,我们的定位的目标为红色框线内的产品信息。

使用开发者工具,定位页面中的产品,可以看到所有产品都存放在class=‘gl-item’的li标签中。可以通过select(".gl-item")确定所有页面中的产品集合。

确定产品后,逐步确定price(产品价格)、title(商品名称)、product_detail_link(商品详情链接)、img_link(图片链接)、评价数量、shop_name(店铺名称)、shop_link(店铺链接)。实际中我们只用到了title这个属性,但是出于习惯,将能用到的内容全部都提取出来,方便以后使用。标签都比较好寻找,就不单列方法,下面是全部元素的定位代码。

r = requests.get(url, params=params, ) r_content = (r.content.decode("utf-8")) content = BeautifulSoup(r_content, 'lxml') product = content.select(".gl-item") for p in product: product_info = {} product_info['number'] = num num = 1 try: # 价格 product_info["price"] = p.select(".p-price i")[0].get_text() # 商品名称 product_info["title"] = p.select('.p-name-type-2 a')[0].attrs['title'].strip(" ") # 商品链接 product_info['product_detail_link'] = p.select('.p-img a')[0].attrs['href'].strip('/') # 图片链接 product_info['img_link'] = p.select('.p-img a img')[0].attrs['source-data-lazy-img'].strip('/') # 评价数量 product_info["评价数量"] = p.select('.p-commit a')[0].get_text() # 商家信息 shop = p.select(".p-shop a") if len(shop) == 0: shop_name = "" shop_link = "" else: # 商铺名称 shop_name = shop[0].get_text() # 商铺链接 shop_link = shop[0].attrs['href'] product_info['shop_name'] = shop_name product_info['shop_link'] = shop_link

在提完当前页之后,我们肯定不能满足只爬取一页的内容,如果只要一页的内容我猜不用爬虫应该更简单。下一步就是不断提取下一页的链接,并不断访问提取数据。

在搜索结果中点击下一页,观察url变化。(比较过程略)

通过观察比较,我们可以得到一个规律。在url中必须传的参数有keyword(搜索关键字)、enc(编码)、s(内容数量)、page(当前页)。其中只有page是变化参数,其他都是固定参数。所以我们可以不断的构建page参数,来访问不同的页面。代码如下:

url = "https://search.jd.com/Search" params = { "keyword": keyword, "enc": "utf-8", "s": 50, } for i in range(1, 200, 2): params['page'] = i r = requests.get(url, params=params, )

通过不断的构建url地址,我们可以访问全部的搜索结果。

保存

通过上面的提取内容代码,我们可以将所有需要的信息放在一个list中,每个list元素是一个product_info字典。通过csv库,将得到的内容保存到csv文件中。

def save_info(product_list,file): fieldnames = ['number','price','title','product_detail_link','img_link',"评价数量",'shop_name','shop_link'] with open(file,'a',newline="") as csvfile: writer = csv.DictWriter(csvfile,fieldnames=fieldnames) writer.writeheader() for product_info in product_list: #写入时需要注意,有些商品名称包含“✅”或“❤”特殊字符,是无法写入的,要做处理 try: writer.writerow(product_info) except: print(str(product_info) "写入错误")

这里需要注意的一点是,因为有些产品名称中包含“✅”,“❤”这样的特殊字符,是无法写入到csv中的,需要对写入代码做异常判断。(偷偷的告诉你,这个错误还真浪费了小编一些时间,一直都是写入报错,后来才找到是特殊字符的锅)

分词

保存文件之后,我们通过另一个函数读取csv中的title字段(这里也可以直接使用爬虫代码中提取的数据,小编只是习惯将数据保存),通过jieba库,对数据进行中文分词。jieba库可以将一个中文字符串进行中文分词,是一个很好用的中文分词库(具体使用方法后续会发笔记)。首先将所有title提取出来,并组合成一个字符串,通过jieba.cut对该字符串进行分词。具体代码如下:

seg_list = jieba.cut(data_string, cut_all=False)

生成词云

在得到分词结果之后,我们要对结果进行加工,得到一个{词:出现次数}的字典,当然为了去除一些无用的词和低频的词,我们还需要一个筛选。筛选代码略。可以通过源码查看。

得到{词:出现次数}的字典之后,我们就可以使用pyecharts库中的WordCloud进行词云生成。具体代码如下:

wordcloud = WordCloud(width=1300, height=620) for k,v in seg_count_bigthan100.items(): word.append(k) count.append(v) wordcloud.add("词云图", word, count, word_size_range=[20, 100],shape="diamond") wordcloud.render()

结果

下面是小编搜索几个关键字之后的词云结果。

情人节:

七夕:

手机:

源码

关注公众号,回复关键字 “ 礼物 ” 领取源码。

一些话

看了这个词云结果,想到的是什么?反正小编是一脑子的懵*,这**跟我想的不一样啊,看了这个结果仍然对我没什么帮助啊,可是已经写完了还能怎么办呢?当然是分享出来给小伙儿伴们看一下了。

代码还有很多需要改进的地方,希望各位大佬轻拍。

0 人点赞