[Python爬虫] 抓取京东商品数据||京东商品API接口采集

本文结构:
一、引言
二、代码分享
三、问题总结

引言

这两天因为一些需求,研究了一下如何爬取京东商品数据。最开始还是常规地使用selenium库进行商品页的商品抓取,后来因为想要获取优惠信息,只能进入到商品详情页进行抓取,想着用selenium库模拟浏览器行为进行页面抓取速度有点慢,就改用了requests库直接发送请求,然后问题就来了:明明在页面看到了优惠满减字段,抓取的结果却是空白的。

百度研究了一番,总算找到了原因。最后因为商品抓取量不大,所以还是乖乖的使用了selenium库进行爬虫。

代码分享

爬虫代码如下:

# -*- coding: utf-8 -*-
"""
爬取京东商品排行榜商品信息
"""from selenium import webdriver
from bs4 import BeautifulSoup
import pandas as pd
import re
import time##京东排行榜地址:https://top.jd.com/writer=pd.ExcelWriter(r"D:\python学习\京东排行榜商品.xlsx")##数据写入的文件##使用selenium模拟浏览器登陆
#需要下载安装chromedriver
driver = webdriver.Chrome(r"C:\chromedriver.exe")
driver.set_page_load_timeout(60)#设置页面最大加载等待时间category = ["手机","平板电脑"]#需要爬取的品类
category_url = ["https://top.jd.com/sale?cateId=653","https://top.jd.com/sale?cateId=2694"]#爬取品类的网页for ci,c in enumerate(category_url,start=0):driver.get(c)#发送请求time.sleep(3)#################################获取排行榜信息###############################333info_name =[] #商品信息tag1 = [] #标签一:x天最低tag2 = [] #标签二:自营/包邮/促销/赠品tag3 = [] #标签三:好评率price = [] #商品价格link = [] #商品详情页bs = BeautifulSoup(driver.page_source,"html.parser")sale_list = bs.findAll("li",class_=re.compile('saleitem'))for s in sale_list:info_name.append(s.find("p",class_ = "saleitem_info_name").get_text())t = s.find("li",class_ = "top_mod_tag_item top_mod_tag_dj")if t is not None:tag1.append(t.get_text())else:tag1.append("")t = s.find("li",class_ = re.compile("top_mod_tag_item top_mod_tag_[^(dj)]"))if t is not None:tag2.append(t.get_text())else:tag2.append("")t = s.find("li",class_ = "top_mod_tag_item",text=re.compile("好评率.*"))if t is not None:tag3.append(t.get_text())else:tag3.append("")price.append(s.find('p',class_ = "saleitem_info_price").get_text())link.append(s.find('a',class_ = "saleitem_link").get("href"))#################进入商品详情页,获取商品的优惠券########################  coupon = []for i,l in enumerate(link, start=1):driver.get(r"https:" + l)time.sleep(3)bs = BeautifulSoup(driver.page_source,"html.parser")try:coupon.append(bs.find("div",class_="summary").find("div",id = "summary-quan").find("span",class_ = "text").get_text())except:coupon.append("")print("抓取品类:%s,第%d个商品优惠券信息完成" %(category[ci],i))time.sleep(3)data = pd.DataFrame({"商品信息":info_name,"标签一(x天最低)":tag1,"标签二(自营/包邮/促销/赠品)":tag2,"标签三(好评率)":tag3,"价格":price,"商品详情页":link,"优惠券":coupon})data.to_excel(writer,sheet_name=category[ci],index=False)driver.close()    

爬虫的步骤很简单。直接使用selenium库webdriver访问需要抓取的网址,然后进行html标签定位,使用Beautifulsoup库进行数据提取,之后使用pandas写入excel文件保存。

抓取结果如下:

图片

问题总结

最开始的问题出在哪儿呢?为什么如果直接使用requests库get请求,结果抓取不到价格数据?

简单代码尝试了一下

import requests
from bs4 import BeautifulSoup
response = requests.get("https://item.jd.com/27009615825.html")
bs = BeautifulSoup(response.content,"html.parser")
print(bs.find("div",class_="summary").find("div",id = "summary-quan").find("span",class_ = "text"))

明明打开浏览器的开发者工具可以看到优惠信息就存放在class属性值为 ‘text’的span标签下,但是抓取到的结果却为空。

图片

输出结果如下:

In[1]: print(bs.find("div",class_="summary").find("div",id = "summary-quan").find("span",class_ = "text"))None

百度了解到的原因是,京东网页中价格等信息并不是存放在静态网页中的,我们使用requests获取到网页源码,进行html解析,只会获取到空值。京东会采取js动态加载数据。那些商品价格、优惠券信息等等,并不是放在静态网页中的。每次加载页面,js脚本都会对数据接口进行调用请求数据,然后返回到页面上。所以,对于动态页面的抓取,一种办法就是借助工具找到js脚本请求的数据接口,使用requests库直接访问该接口获取数据。如价格信息就放在:

https://p.3.cn/prices/mgets?callback=jQuery6775278&skuids=J_(skuid)

其中链接最后括号里存放商品的sku id,比如:

https://p.3.cn/prices/mgets?callback=jQuery6775278&skuids=J_27009615825

商品的sku id可以在商品详情页的html抓取到。

关于京东的数据抓取,网上能百度到有完整的项目,有兴趣的可以了解一下:

CSDN地址:
https://blog.csdn.net/Kandy_Ye/article/details/70183110
Github代码:
https://github.com/KandyYe/JDSpider

另外,更加简单的一种办法就是使用selenium库进行数据采集了。selenium模拟浏览器行为,等到页面加载完成后,再获取完整的数据源码,所以在处理数据的时候就不需要担心我们抓取不到啦。但是有点小缺陷就是,selenium库比requests要慢。

据说还有一个两者的结合体——requestium,或许可以有更好

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

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

相关文章

【5G VoNR】VoNR流程简述

博主未授权任何人或组织机构转载博主任何原创文章,感谢各位对原创的支持! 博主链接 本人就职于国际知名终端厂商,负责modem芯片研发。 在5G早期负责终端数据业务层、核心网相关的开发工作,目前牵头6G技术研究。 博客内容主要围绕…

重写equals()方法为什么同时要重写hashcode()

equals()方法 equals()方法是Object类中的一个方法,在Object类中,equals等同于。 在不同的类中,往往会对equals()按需求进行重写。重写的目的都是:用于比较两个对象是否 "相等"。如果两个对象的内容相同,那…

fiddler移动端抓包

步骤 1、手机和电脑必须在同一个局域网: 1)手机和电脑连同一个WiFi; 2)手机连WiFi,电脑用网线连接开启这个WiFi的无线路由; 3)电脑开热点,手机连热点 2、开启fiddler代理&#xff…

faskapi好用的模板

在Web开发领域,FastAPI作为一个基于Python的高性能Web框架,因其快速、易用以及强大的功能而备受开发者青睐。关于FastAPI的好用模板,这里介绍几个不同角度的模板或项目框架,以帮助您更好地理解和选择适合自己的起点。 1. FastAPI…

第十一节 动态面板加密解密显示

在原型中我们经常会遇到文件加密与解密显示问题,下面以一个简单案例来说明实现怎么切换明文与密文不同显示方式案例说明; 1、添加动态面板 2、设置加密与不加密 3、添加动作事项 注意为可见时要设置面板状态向前循环,上一项,否则…

新闻第一线|随身WiFi市场乱象与破局者:格行以品质重塑行业信任、随身WiFi行业标杆!

在快速发展的移动互联网时代,随身WiFi凭借用网方便性价比高也随之爆火。然而,近年来,随身WiFi市场却陷入了“内卷”与“信任危机”的双重困境,消费者在选择时往往面临质量问题。在此背景下,格行以其独特的品牌理念和扎…

Linux网络配置管理

目录 一、网络配置 1. 网卡配置 2. 路由 二、 网络信息查看 1.netstat 2. ss 三、 额外的命令 time 一、网络配置 之前我们学过 ifconfig ,这个命令可以查看网络接口的地址配置信息,我们只知道它可以查看接口名称、IP 地址、子网掩码等。 但是&a…

笔记:Newtonsoft.Json 序列化接口集合

在使用 Newtonsoft.Json 序列化接口集合时,一个常见的挑战是如何处理接口的具体实现,因为接口本身并不包含关于要实例化哪个具体类的信息。为了正确序列化和反序列化接口集合,你需要提供一些额外的信息或使用自定义的转换器来指导 Newtonsoft…

【Unix/Linux】$bash-3.2是什么

bash-3.2 指的是Bourne Again Shell(Bash)的3.2版本。 Bash是一个广泛使用的Unix shell和命令语言,是GNU项目的一部分,也是许多Linux发行版和Unix系统的默认shell。 以下是一些关于Bash 3.2的要点: 1. 兼容性&#…

MySQL 进阶(二)【索引详解】

前言 程序员避不开和数据库打交道,大数据更是如此,不管是 MySQL、Oracle、SQL Server 这些 OLTP 数据库,还是Greeplum、StarRocks、Hive、Spark SQL、Flink SQL、ClickHouse 等 OLAP 数据库,SQL 都是最基础最重要的能力&#xff0…

DFS回溯剪枝|KMP通过数组记录减少判断子字符串|思路

KMP|DFS回溯剪枝 #1、NC149kmp 初步思路: 两层for循环,一个T的字符开始与 S的字符比较,挨个比较,遇到不同就continue当前T的字符,重复步骤》效率太低,超时 eg: TABSABABABD SABABD S!A时&#…

开发个人Go-ChatGPT--2 环境搭建

开发个人Go-ChatGPT–2 环境搭建 2.1 环境要求 Golang 1.22 Etcd Docker Redis Mysql 2.2Docker本地开发环境搭建 这里使用 Docker Compose 来编排管理我们的容器,docker-compose.yaml: version: 3.8services:mysql:image: mysql:8.0.18contain…

【目录】阅读须知!全博文、专栏大纲

首先要和大家说一下,博主的文章并不是想到哪里写到哪里,而是以整个大后端为主题,成体系的在写专栏,从和后端紧相关的计算机核心课程开始、到JAVA SE、JAVA EE、到数据库、MQ等各类中间件、再到业务场景、性能优化。当然也会涉及一…

七、构造函数与析构函数

七、构造函数与析构函数 构造函数析构函数调用机制构造函数的调用机制析构函数的调用机制总结 构造函数分类深拷贝与浅拷贝浅拷贝(Shallow Copy)深拷贝(Deep Copy)示例 初始化参数列表委托构造default、delete和 explicitdefaultd…

【Go】常见的变量与常量

变量 常见的变量声明方式 一、声明单个变量的多种方式 1.声明一个变量初始化一个值 //声明变量 默认值是0,var a int//初始化一个值a 1fmt.Println(a) 2. 在初始化的时候省去数据类型,通过值自动匹配当前的变量的数据类型 var b 2fmt.Println(&quo…

html+css+js随机验证码

随机画入字符、线条 源代码在图片后面 点赞❤️关注&#x1f60d;收藏⭐️ 互粉必回 图示 源代码 <!DOCTYPE html> <html lang"en"> <head> <meta charset"UTF-8"> <meta name"viewport" content"…

【java web 01】3小时快速学习前端知识(收藏备用)

3小时快速学习前端知识【全栈专用】 一、教程简介1.1 Java 开发为何学Web技术1.2 课程设计1.3 课前准备 二、HTML2.1 Html简介2.1.1 HTML、CSS、JS分别有什么作用2.1.2 什么是HTML2.1.3 什么是标记语言 2.2 Hello&#xff0c;Html2.2.1 HTML基础结构2.2.2 专业词汇2.2.3 语法细…

C++入门(C语言过渡)

文章目录 前言一、C关键字二、命名空间三、C输入&输出四、缺省参数五、函数重载六、引用七、inline八、nullptr总结 前言 C是一种通用的、高级的、静态类型的编程语言&#xff0c;它在20世纪80年代由丹尼斯里奇创建的C语言基础上发展而来。以下是C发展的一些重要里程碑。 1…

Updates were rejected because the tip of your current branch is behind

Git在push推送时&#xff0c;报错提示信息如下&#xff1a; hint: Updates were rejected because the tip of your current branch is behind hint: its remote counterpart. If you want to integrate the remote changes, hint: use git pull before pushing again. hint: …

[个人感悟] 消息队列应该考察哪些问题?

前言 消息队列. 不论是Java内部提供的LinkedBlockingQueue, 还是当下主流的中间件RabbitMQ, Kafka, RockMQ. 其本质上都是一个削峰填谷的工具. 我们都知道, 请求和流量都有可能瞬间很高, 或者很低. 所以, 很多时候, 我们需要请求存储起来, 或者使用异步的方式, 来匀速的处理过…