Python爬虫篇(四):京东数据批量采集

京东数据批量采集

前言

        一年一度的端午节又到了,甜咸粽子之争也拉开了帷幕,它价格高昂,它味道鲜美,然而,默默无名的它却备受广大民众喜爱!好家伙,一看就是老qq看点了

图片

,那咱们能做些什么呢,当然是选择盘它啊,今天咱们就看看京东上粽子的行情。

图片

爬取京东数据

        发起请求-获取响应内容-解析内容-保存内容,还是熟悉的老四步曲。

1. 发起请求,获取响应内容

        浏览器打开京东(https://www.jd.com),搜索“粽子”,点击下一页

图片

        可以看到url的构造是https://search.jd.com/Search?keyword=%E7%B2%BD%E5%AD%90&qrst=1&stock=1&page=3&s=53&click=0,提取主要的参数keyword(搜索词)和page(页码),那么主要的url为:https://search.jd.com/Search?keyword=%E7%B2%BD%E5%AD%90&page=3,keyword是粽子,固定的,变化的参数是page,我们先请求下:

import requests
url = 'https://search.jd.com/Search?keyword=%E7%B2%BD%E5%AD%90&page=3'headers = {'Host': 'search.jd.com',           'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:77.0) Gecko/20100101 Firefox/77.0',            'Accept-Language': 'zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2'}r = requests.request('GET',url=url,headers=headers)print(r.text)

图片

2.解析数据

        解析数据当然要用到最强大也是最方便的BeautifulSoup了,先看我们需要采集的数据在哪:

图片

        咱们来采集主要的四个数据,图片,价格,描述,店铺名称,打开调试器,分析页面构造:

图片

图片

        我们可以看到商品的数据在一个id为J_goodsList的div里,内层的每一个li标签包含了一个商品的全部信息,然后我们就可以开始解析了:

from bs4 import BeautifulSoupimport requests
url = 'https://search.jd.com/Search?keyword=%E7%B2%BD%E5%AD%90&page=' + str(page)headers = {'Host': 'search.jd.com',           'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:77.0) Gecko/20100101 Firefox/77.0',           'Accept-Language': 'zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2'}r = requests.request('GET',url=url,headers=headers)div = BeautifulSoup(r.text,'lxml').find_all('div',id='J_goodsList')[0]  # 拿到主要divitems = BeautifulSoup(str(div),'lxml').find_all('li',class_='gl-item')  # 商品列表print(items)print(len(items))

        打印一下,发现只采集到了30个li标签,然而通过网页我们可以发现每页是有60个商品的,也就是说这只拿到了前30个数据,可以猜想京东是通过ajax加载数据的,打开调试器,查看网络,鼠标往下滑:

图片

        可以看到出现了后边30条数据的请求,分析链接构造,page参数为偶数,之前的30条数据page参数为奇数,也就是第一页的数据就是page为1和2的数据,商品总共是100页,也就是page从1-200,链接搞定,我们继续解析详细数据:

items = BeautifulSoup(str(div),'lxml').find_all('li',class_='gl-item'result = []for item in items:    desc = BeautifulSoup(str(item), 'lxml').find('div', class_='p-name p-name-type-2').find_all('a')[0].text.replace('\n','') # 去除换行符    img = BeautifulSoup(str(item), 'lxml').find('div', class_='p-img').find_all('img')[0].get('src')    shop = BeautifulSoup(str(item), 'lxml').find('div', class_='p-shop').find_all('a')[0].text    price = BeautifulSoup(str(item),'lxml').find_all('div',class_='p-price')[0].text.replace('\n','').split('¥')[1]  # 去除换行符和格式数据result.append([shop,img,price,desc])

        完整获取数据:

    result = []    for page in range(1, 201):        print('正在采集第' + str(page) + '页')        url = 'https://search.jd.com/Search?keyword=%E7%B2%BD%E5%AD%90&page=' + str(page)        headers = {'Host': 'search.jd.com',                   'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:77.0) Gecko/20100101 Firefox/77.0',                   'Accept-Language': 'zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2'}        r = requests.request('GET',url=url,headers=headers)        print(r.text)        try:            div = BeautifulSoup(r.text,'lxml').find_all('div',id='J_goodsList')[0]            items = BeautifulSoup(str(div),'lxml').find_all('li',class_='gl-item')            for item in items:                try:                    desc = BeautifulSoup(str(item), 'lxml').find('div', class_='p-name p-name-type-2').find_all('a')[0].text.replace('\n','')                except Exception as e:                    desc = '无'                try:                    img = BeautifulSoup(str(item), 'lxml').find('div', class_='p-img').find_all('img')[0].get('src')                except Exception as e:                    img = '无'                try:                    shop = BeautifulSoup(str(item), 'lxml').find('div', class_='p-shop').find_all('a')[0].text                except Exception as e:                    shop = '无'                try:                    price = BeautifulSoup(str(item),'lxml').find_all('div',class_='p-price')[0].text.replace('\n','').split('¥')[1]                except  Exception as e:                    price = '无'                result.append([shop,img,price,desc])        except Exception as e:            pass

3.保存数据

import xlwt
workExcel = xlwt.Workbook(encoding='utf-8')workSheet = workExcel.add_sheet('data')workSheet.write(0, 0, '店铺')workSheet.write(0, 1, '图片')workSheet.write(0, 2, '价格')workSheet.write(0, 3, '描述')i = 0for data in result:    i += 1    workSheet.write(i, 0, data[0])    workSheet.write(i, 1, data[1])    workSheet.write(i, 2, data[2])    workSheet.write(i, 3, data[3])workExcel.save(r'C:\Users\Administrator\Desktop\data.xls')

图片

分析数据

        先看下粽子价格的top5:

import pandas as pd
wb = pd.read_excel('data.xls', sheet_name='data')wb = pd.DataFrame(wb.rename(columns = {u"店铺":'shop',u"价格":'price',u"描述":'desc'}))df = wb[['shop', 'desc', 'price']]df1 = df.sort_values(by="price", axis=0, ascending=False)print(df1.iloc[:5, :])

图片

        好家伙,2265.5元,看来是吃不起了......还是去买小区门口5块钱3个的吧

图片

      再来参照淘宝的价格区间给粽子价格划分下:

            贫民窟:小于22元的(底层人民专属)

            平民区:大于22元小于115元的

            小康家庭:大于115元小于633元的

            富人区:大于633元的

wb = pd.read_excel('data.xls', sheet_name='data')wb = pd.DataFrame(wb.rename(columns = {u"店铺":'shop',u"价格":'price',u"描述":'desc'}))df = wb[['shop', 'desc', 'price']]# 统计出现次数,方便绘图primary = df.query('price <= 22').shop.count()intermediate = df.query('price > 22 and price <= 115').shop.count()senior = df.query('price > 115 and price <= 633').shop.count()rich = df.query('price > 633').shop.count()print(primary, intermediate, senior, rich)

      绘制饼图:

# 显示中文问题plt.rcParams['font.sans-serif'] = ['SimHei']label_list = ['22元以下', '22-115元', '115-633元', '633元以上']size = [primary, intermediate, senior, rich]# 各部分颜色color = ['red', 'green', 'blue', 'yellow']# 各部分突出值explode = [0, 0, 0, 0.1]patches, l_text, p_text = plt.pie(size, explode=explode, colors=color, labels=label_list, labeldistance=1.1, autopct="%1.1f%%", shadow=False, startangle=90, pctdistance=0.6)# 设置横轴和纵轴大小相等,这样饼才是圆的plt.axis('equal')plt.legend(loc='upper left')plt.show()

图片

        看来平民还是占多数的嘛!

图片

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/581872.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

07.kubernetes客户端部署

kubernetes 客户端部署 主要是配置 kubectl 完成以下两个操作: 首先是要实现通过命令行连接到Kubernetes的apiserver然后就是创建必要的 ClusterRoleBinding 实现 kubelet bootstrapping CSR 的自动验签kubelet bootstrapping主要涉及以下两个问题,官方文档已经给出详细的介…

Flink1.17实战教程(第七篇:Flink SQL)

系列文章目录 Flink1.17实战教程&#xff08;第一篇&#xff1a;概念、部署、架构&#xff09; Flink1.17实战教程&#xff08;第二篇&#xff1a;DataStream API&#xff09; Flink1.17实战教程&#xff08;第三篇&#xff1a;时间和窗口&#xff09; Flink1.17实战教程&…

BOM是什么? BOM核心有哪些?可以实现哪些功能?

文章目录 ❄️一、BOM是什么❄️二、BOM的核心有哪些&#x1f9ff;window 对象——BOM核心&#x1f365;Document对象&#x1f3af;Frames 对象&#x1f95d;Navigator 对象&#x1f9eb;History对象&#x1f4c0;Location对象&#x1f36a;Screen对象 ❄️三、BOM可以实现的功…

从零学算法103

103.给你二叉树的根节点 root &#xff0c;返回其节点值的 锯齿形层序遍历 。&#xff08;即先从左往右&#xff0c;再从右往左进行下一层遍历&#xff0c;以此类推&#xff0c;层与层之间交替进行&#xff09;。 示例 1&#xff1a; 输入&#xff1a;root [3,9,20,null,null,…

聚焦亚马逊云科技 re:Invent re:Cap专场,重构生成式AI的无限可能!

摘要&#xff1a;12月14日至17日&#xff0c;第十二届全球软件案例研究峰会(简称TOP100summit)在北京国际会议中心成功举办&#xff0c;亚马逊云科技资深开发者布道师郑予彬、亚马逊云科技解决方案研发中心应用科学家肖宇、可以科技产品负责人曹临杰、亚马逊云科技解决方案架构…

Hive实战:统计总分与平均分

文章目录 一、实战概述二、提出任务三、完成任务&#xff08;一&#xff09;准备数据文件1、在虚拟机上创建文本文件2、将文本文件上传到HDFS指定目录 &#xff08;二&#xff09;实现步骤1、启动Hive Metastore服务2、启动Hive客户端3、创建Hive表&#xff0c;加载HDFS数据文件…

PO 发布SAP SProxy->外围系统 WebService

通信概览图 外围系统与PO、SAP的请求响应通信过程大致可以用下图描述 &#xff08;个人整理所得&#xff0c;可能有误&#xff0c;欢迎指正&#xff09; 1. 前期准备 1.1 外围系统提供WebService接口 以A系统的RFC发布WebService接口 RFC发布WebService接口 获取到WSDL地…

CSS样式详解之伪类元素及CSS3选择器

目录 一、伪类元素二、CSS3选择器1. 相邻选择器&#xff08;&#xff09;2. 兄弟选择器&#xff08;~&#xff09;3. 指定选择器&#xff08;nth-of-type(n)&#xff09;4. 子元素指定选择器&#xff08;子元素匹配选择器&#xff09;5. 属性选择器① [ 属性名 ]② [ 属性名属性…

什么是MLOps?

人工智能&#xff08;AI&#xff09;和机器学习&#xff08;ML&#xff09;应用激动人心的发展浪潮也许会让人相信&#xff0c;企业交付ML产品的能力也在迅速提高。但现实情况是&#xff0c;ML内部流程很难跟上行业的整体发展……但若以MLOps的形式则有希望解决此问题&#xff…

面试复盘5——后端开发——一面

前言 本文主要用于个人复盘学习&#xff0c;因此为保障公平&#xff0c;所以本文不指出公司名&#xff0c;题目编号只是为了自己区别而已。对待面经&#xff0c;望读者还是更多从其中学习总结&#xff0c;而不是去碰原题。 面试岗位信息 后端开发秋招&#xff0c;上海某大中…

08.Kubernetes node 节点部署

Kubernetes node节点部署比较繁琐,需要配置一堆的配置文件和证书,手动配置特别容易出错。 这就体现出用脚本部署的优势,将繁琐的操作批量自动化 一是极大的提升效率(尤其是节点比较多的时候)二是确保所有节点配置的统一性(配置统一很重要,因为正常情况下,如果某个节点出…

一文让你读懂Python中的Response对象

目录 引言 一、Response对象简介 二、Response对象的组成 三、Response对象的创建 1、使用内置的http.client模块&#xff1a; 2、使用requests库&#xff1a; 3、使用Django框架&#xff1a; 四、Response对象的处理 1、发送给客户端&#xff1a; 2、设置响应头&…

centos 编译安装 libxml-2.0

centos 编译安装 libxml-2.0 下载地址 我下载的 libxml2-2.9.12.tar.gz 版本 下载后解压&#xff0c;进入解压后的目录 执行&#xff1a; ./configure make && make install安装过程中出现 <Pyghon.h> 找不到的问题&#xff0c;指定了路径之后还是找不到&…

来看看这个技术,这才是UPS监控的最好方式!

在现代社会中&#xff0c;信息技术的持续发展使得机房UPS监控变得至关重要。机房是企业信息系统的核心&#xff0c;UPS监控系统能够确保在电力故障或其他问题发生时&#xff0c;机房设备能够持续稳定运行&#xff0c;从而保障数据的安全性和可用性。 客户案例 金融机构 河北某…

2660. 保龄球游戏的获胜者 --力扣 --JAVA

题目 给你两个下标从 0 开始的整数数组 player1 和 player2 &#xff0c;分别表示玩家 1 和玩家 2 击中的瓶数。 保龄球比赛由 n 轮组成&#xff0c;每轮的瓶数恰好为 10 。 假设玩家在第 i 轮中击中 xi 个瓶子。玩家第 i 轮的价值为&#xff1a; 如果玩家在该轮的前两轮的任何…

fork函数详解【Linux】

fork函数详解【Linux】 fork函数的概念fork调用后的底层细节解释fork学习中的一些笔记和问题fork的写实拷贝深拷贝的策略 fork调用失败的原因 fork函数的概念 调用fork函数可以在已存在的进程中创建一个子进程&#xff0c;此时&#xff0c;新进程叫做子进程&#xff0c;原进程叫…

SpringBoot当中的Singleton和Prototype详解

在Spring Boot中&#xff0c;Singleton和Prototype是两种Bean的作用域。这两种作用域决定了Spring容器如何创建和管理Bean的实例。 Singleton&#xff08;单例&#xff09;&#xff1a; 当一个Bean被配置为Singleton作用域时&#xff0c;Spring容器在启动时只会创建该Bean的一个…

Spring Boot 入参校验及全局异常处理

版本依赖 JDK 17 Spring Boot 3.2.0 源码地址&#xff1a;Gitee Spring Boot validation spring-boot-starter-validation是基于hibernate-validator的实现&#xff0c;在Spring Boot项目中直接导入spring-boot-starter-validation即可。 Valid 和 Validated 的区别 适用范围…

《对话品牌》——活到老“养”到老

本期节目《对话品牌》栏目组邀请到了深圳壹常青健康管理有限公司董事长邬锡娣女士参加栏目录制&#xff0c;分享其企业故事&#xff0c;树立品牌形象&#xff0c;提升品牌价值&#xff01; 节目嘉宾&#xff1a;邬锡娣女士 节目主持人&#xff1a;董倩 节目播出平台&#xf…

在线教育系统源码解读:定制化企业培训APP的开发策略

当下&#xff0c;企业培训正经历着一场数字化的迭代&#xff0c;定制化企业培训APP应运而生&#xff0c;成为提升员工技能、推动企业发展的重要工具。下文小编将与大家一同深入了解在线教育系统的源码&#xff0c;探讨开发定制化企业培训APP的策略&#xff0c;以满足不同企业的…