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.hqwc.cn/news/319383.html

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

相关文章

电锯切割狂

欢迎来到程序小院 电锯切割狂 玩法&#xff1a;把木块切成等分的碎片&#xff0c;每关都会有切割次数&#xff0c;木块数&#xff0c;切割越均匀分数越搞&#xff0c; 有简单、正常、困难、专家版&#xff0c;快去解锁不同版本进行切割吧^^。开始游戏https://www.ormcc.com/pl…

2023到2024年:前端发展趋势展望

本文探讨了2023年至2024年之间前端领域的发展趋势。我们将关注以下几个方面的变化&#xff1a;无代码/低代码开发的兴起、WebAssembly的广泛应用、跨平台技术的发展、人工智能在前端的应用以及用户体验的不断优化。 随着技术的飞速发展&#xff0c;前端开发在推动互联网与移动应…

numpy数组05-numpy的索引和切片

numpy中可以对其中的某一行&#xff08;列&#xff09;进行数据处理。 上节课我们已经取出了CSV文件中的二维数组&#xff0c;本次对这个二维数组为例&#xff0c;进行练习操作。 示例代码如下&#xff1a; import numpy as npus_file_path "US_video_data_numbers.cs…

【响应式编程-02】Lambda的语法格式和使用

一、简要描述 Lambda的语法格式Lambda的使用 二、Lambda的语法格式 (parameters) -> {statements;}(pararmeters) -> expression 1、(parameters) -> {statements;} parameters: 函数的参数列表statements: 执行语句-> : 使用指定参数去完成某个功能 public int me…

【基础篇】十一、JVM方法区

文章目录 1、方法区2、方法区的位置3、模拟方法区的溢出4、方法区的字符串常量池5、常量池案例6、String的intern方法7、静态变量的存放位置 1、方法区 方法区线程共享&#xff0c;存了以下几部分&#xff1a; 类的元信息运行时常量池字符串常量池 类的元信息&#xff0c;即…

05-SpringCloud-RabbitMQ-概述

RabbitMQ 1.初识MQ 1.1.同步和异步通讯 微服务间通讯有同步和异步两种方式&#xff1a; 同步通讯&#xff1a;就像打电话&#xff0c;需要实时响应。 异步通讯&#xff1a;就像发邮件&#xff0c;不需要马上回复。 两种方式各有优劣&#xff0c;打电话可以立即得到响应&am…

FPGA高端项目:纯verilog的 10G-UDP 高速协议栈,提供7套工程源码和技术支持

目录 1、前言免责声明更新说明 2、相关方案推荐我这里已有的以太网方案本协议栈的千兆网UDP版本1G 千兆网 TCP-->服务器 方案1G 千兆网 TCP-->客户端 方案10G 万兆网 TCP-->服务器客户端 方案 3、该UDP协议栈性能4、详细设计方案设计架构框图网络调试助手GT资源使用GT…

Ubuntu软件和vmware下载

https://cn.ubuntu.com/download/desktop VMware 中国 - 交付面向企业的数字化基础 | CN

vc2017编译从github网站上下载的源码

以ZLmediakit为例 1.下载软件 cmakehttps://github.com/Kitware/CMake/releases/download/v3.20.5/cmake-3.20.5-windows-x86_64.zip Microsoft Visual Studio https://my.visualstudio.com/Downloads?qvisual%20studio%202017&wt.mc_ido~msft~vscom~older-downloads …

开源游戏引擎:创造无限可能 | 开源专题 No.56

godotengine/godot Stars: 62.6k License: MIT Godot Engine 是一个功能强大的跨平台游戏引擎&#xff0c;可用于创建 2D 和 3D 游戏。它提供了一套全面的常见工具&#xff0c;让用户可以专注于制作游戏而不必重复造轮子。该引擎支持将游戏一键导出到多个平台上&#xff0c;包…

增删改查语句实现了解不同的函数与特殊字符unionunion all区别

一、crud&#xff08;增删改查&#xff09; 1.1、查询 概念&#xff1a; 查询数据是指从数据库中根据需求&#xff0c;使用不同的查询方式来获取不同的数据&#xff0c;是使用频率最高、最重要的操作 注&#xff1a;在MySQL中&#xff0c;当执行一条SQL语句后&#xff0c;系…

探索 Vue 实例方法的魅力:提升 Vue 开发技能(下)

&#x1f90d; 前端开发工程师&#xff08;主业&#xff09;、技术博主&#xff08;副业&#xff09;、已过CET6 &#x1f368; 阿珊和她的猫_CSDN个人主页 &#x1f560; 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 &#x1f35a; 蓝桥云课签约作者、已在蓝桥云…